介绍

相信所有的前端小伙伴对 forEach() 方法并不陌生,它实现了对数组的每个元素执行一次给定的函数。可在使用中,经常希望跟 for 一样,在循环过程中,某个判断成立后跳出这个循环。本期我们就将聊聊 forEach 的实现及使用,以及跳不出去的原因,还有跳出方案。

正文

循环对比

众所周知,for 循环跳出非常容易:

let arr = [...new Array(10).keys()]
for(let i = 0; i < arr.length;i++){
	console.log(`item:${arr[i]}`)
	if(arr[i]>5) break;
}

可是对于 forEach() 方法或许这点就让人失望了,它是从头走到底的,不仅 return 都是无效的,而且 break 还是直接报错;

为何无法跳出

为了了解无法跳出循环的原因,我们就简单手写一个 forEach 方法,来探查这个原因。
我们先来分析一下,语法和传参:

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
  • callback:数组中每个元素需要执行的回调函数
    • currentValue:当前元素的值。
    • index:当前元素的索引值。
    • array:当前所操作的数组。
  • thisArg:可选参数。当执行回调函数 callback 时,用作 this 的值。
   	 Array.prototype.myForEach = function(callback,self){
   	    let _arr = [...this];
   	    for(let i = 0;i<_arr.length;i++){
   	        callback.call(self,_arr[i],i,_arr)
   	    }
   	}

如你所见寥寥几句就可以实现出我们的 forEach 方法了,而且,由此可见,我们了解到它本身也是借用的 for 循环 来处理当前元素,执行回调方法,在这个方法里肯定是跳不出来的。那有什么办法能让回调函数中断呢?对,就是抛出异常。

实现跳出

现在我们就来用抛出异常的方式来完成这个跳出任务。

let arr = [...new Array(10).keys()];
try{
    arr.forEach(item=>{
        console.log(`item:${item}`)
        if(item>5) throw new Error("break");
    })
}catch(err){
    if(err.message === "break")	
        console.log("break success!")
    else 
        console.error(err)
}

我们这里用了抛出异常的方式直接让回调函数报错来实现,但是还要注意一点,最好还要传入一个异常错误的 message ,我这里定为 字符串信息break,因为我们在运行时还有可能报出别的错误,有了这个标识就能识别处理哪个是正常的跳出循环,哪个是真正的执行错误。

结语

其实不仅仅是 forEach() 方法,还有一个平时经常使用的 map() 方法也是大同小异的,可以用抛出异常来实现跳出循环的操作。但我们其实也完全可以使用 some() , every() 等方法来提前验证好,或者使用 findIndex() 去检测条件捕获索引后再进行二次遍历处理。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐