不能被终止的forEach?
面试官:你有什么办法终止 forEach 循环吗?
我:emm,没办法。
面试官:面试到此结束!
我:???
为什么我认为无法终止 forEach 循环?
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
array.forEach((it) => {
if (it >= 0) {
console.log(it)
return // or break
}
})
这段代码没问题,我们甚至还可以模拟实现一下forEach
Array.prototype.forEach2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
while (i < length) {
if (this.hasOwnProperty(i)) {
// Note here:Each callback function will be executed once
callback.call(thisCtx, this[ i ], i, this)
}
i++
}
}
是的,当我们使用“forEach”迭代数组时,回调将为数组的每个元素执行一次,并且我们无法提前终止它。
三种方法终止 forEach
前面说的都没错,但是其实我们有三种特殊方法来终止 forEach 循环
# 抛出错误
当我们找到第一个大于或等于0的数字后,这段代码将无法继续。所以控制台只会打印出0。
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
try {
array.forEach((it) => {
if (it >= 0) {
console.log(it)
throw Error(`We've found the target element.`)
}
})
} catch (err) {
}
# 设置数组长度为0
我们还可以通过将数组的长度设置为0来中断forEach。如果数组的长度为0,forEach将不会执行任何回调。
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
array.forEach((it) => {
if (it >= 0) {
console.log(it)
array.length = 0
}
})
# 使用splice删除数组的元素
思路和方法2一样,如果能删除目标元素后面的所有值,那么forEach就会自动停止。
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
array.forEach((it, i) => {
if (it >= 0) {
console.log(it)
// Notice the sinful line of code
array.splice(i + 1, array.length - i)
}
})
请用 for OR some
虽然这三种方法能够终止 forEach 循环,但是并不推荐在实际工作中使用这些方式,因为实在太过恶臭。最好还是使用 for 或者 some 来实现。
for
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
for (let i = 0, len = array.length; i < len; i++) {
if (array[ i ] >= 0) {
console.log(array[ i ])
break
}
}
some
const array = [ -3, -2, -1, 0, 1, 2, 3 ]
array.some((it, i) => {
if (it >= 0) {
console.log(it)
return true
}
})