Write a longer break and continue

break 与 some、every

Personal likes to use forEachto replace the forcycle. But sometimes we found the implementation process is required break. At this point, you have to switch back to the general forcirculation. Meet the following example logic:

let arr = [1, 2, 3, 4, 5]
let text = ''
for (let v of arr) {
  if (v === 3) { 
    break
  }
  text += v + ','
}
console.log(text) // "1,2,"
复制代码

Today to see the article The thought that since somethe implementation logic itself is short-circuited, that is, upon return truesubsequent iteration is no longer enforced, so why not use someto replace forEachit?

let arr = [1, 2, 3, 4, 5]
let text = ''
arr.some(v => {
  if (v === 3) { 
    return true
  }
  text += v + ','
})
console.log(text) // "1,2,"
复制代码

Under normal circumstances, we someall use it to return results. And this does not take its return value fuss approach, regarded as a signal of the code to read: it will only use its simple cycle Bale. Of course, so write code readability is not very high. But it is to replace forone way.

Similarly, everyalso a short circuit, of course, may be substituted break. However, to ensure that breakthe previous iteration returns true:

let arr = [1, 2, 3, 4, 5]
let text = ''
arr.every(v => {
  if (v === 3) { 
    return
  }
  text += v + ','
  return true
})
console.log(text) // "1,2,"
复制代码

This article sent to the circle of friends, friends say this does not look so "pure". We recommended reduceto achieve, regardless of performance, after all, how many empty iterative performance is not wasted. If you want to replace breakthe logic, you have to use a number flagto achieve, such as:

let arr = [1, 2, 3, 4, 5]
let text = arr.reduce(function(p, c) {
  if (this.break) {
    return p
  }
  // ...
  if (c === 3) {
    this.break = true
    return p
  }
  return p + c + ','
}.bind({}), '')
console.log(text) // "1,2,"
复制代码

Also on "pure", if a function package, the pure:

function formatter(arr) {
  let text = ''
  arr.some(v => {
    if (v === 3) { 
      return true
    }
    text += v + ','
  })
  return text
}
let arr = [1, 2, 3, 4, 5]
console.log(formatter(arr)) // "1,2,"
复制代码

There are also users a message, you can use a recursive way to do it. forAre recursive loop itself can be replaced. The general breakconditions, just to be a recursive exports. Recursive example of the present example:

function formatter(arr, text = '', i = 0) {
  if (arr.length == 0 || arr[i] == '3') {
    return text
  }
  text += arr[i] + ','
  return formatter(arr, text, ++i)
}
let arr = [1, 2, 3, 4, 5]
console.log(formatter(arr)) // "1,2,"
复制代码

continue 与 return

As continueWell. . .

let arr = [1, 2, 3, 4, 5]
let text = ''
for (let v of arr) {
  if (v === 3) { 
    continue
  }
  text += v + ','
}
console.log(text) // "1,2,4,5,"
复制代码

The answer is simple accident, forEachdirectly returnlike:

let arr = [1, 2, 3, 4, 5]
let text = ''
arr.forEach(v => {
  if (v === 3) { 
    return
  }
  text += v + ','
})
console.log(text) // "1,2,4,5,"
复制代码

If continueand breakexist it? for example:

let arr = [1, 2, 3, 4, 5]
let text = ''
for (let v of arr) {
  if (v === 2) {
    continue
  }
  if (v === 4) { 
    break
  }
  text += v + ','
}
console.log(text) // "1,3,"
复制代码

Only somelike, anyway array that several API, are in essence forcycle.

let arr = [1, 2, 3, 4, 5]
let text = ''
arr.some(v => {
  if (v === 2) {
    return
  }
  if (v === 4) { 
    return true
  }
  text += v + ','
})
console.log(text) // "1,3,"
复制代码

And every place some need to pay attention

someArray function used to determine whether at least one element satisfies condition callback function. At this time, the callback function may be called a predicate function (i.e., the judgment is not meant). Specification document in someis so realized:

Click to expand
  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".
  3. Let len be ToUint32(lenValue).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let k be 0.
  7. Repeat, while k < len
    1. Let Pk be ToString(k).
    2. Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument Pk.
    3. If kPresent is true, then
      1. Let kValue be the result of calling the [[Get]] internal method of O with argument Pk.
      2. Let testResult be the result of calling the [[Call]] internal method of callbackfn with T as the this value and argument list containing kValue, k, and O.
      3. If ToBoolean(testResult) is true, return true.
    4. Increase k by 1.
  8. Return false.

JS analog with its core logic is as follows:

Array.prototype.some = function(callbackfn, thisArg) {
  let len = Number(this.length)
  let k = 0;
  while(k < len) {
    let Pk = String(k)
    if (Pk in this) {
      let kValue = this[Pk]
      if (callbackfn.call(thisArg, kValue, k, this)) {
        return true
      }
    }
    k++
  }
  return false
}
复制代码

As can be seen, the callback return value is encountered true, then the function will return directly to an end. This is the kind of short circuit algorithm, not all callbacks are executed again, and then finally find all the values. everyIs similar, but in contrast, the callback return value is encountered false, the overall direct return falseof.

Semantic representation from the realization is concerned, someit is to say: there is a success, I will be successful , but everyis saying: there is a failure, I would have failed .

In addition to stress that can be seen from the realization, when the sparse array index value does not exist, the callback function is not performed. For example, the example callback performed only three times (also other similar API).

let arr = [1, 2, 3]
delete arr[1]
arr[5] = 6
console.log("1" in arr) // false
console.log(arr) // [1, empty, 3, empty × 2, 6]
arr.some(v => {
  console.log(v) // 1 3 6
})
复制代码

So empty array, regardless of the callback function to write, the result is still false:

[].some(_ => true) // false
复制代码

Finished article.

Reproduced in: https: //juejin.im/post/5d08a565e51d45773d468614

Guess you like

Origin blog.csdn.net/weixin_34297300/article/details/93163424