介绍
定制设计相信所有的前端小伙伴对 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;}
- 1
- 2
- 3
- 4
- 5
可是对于 forEach() 方法或许这点就让人失望了,它是从头走到底的,不仅 return 都是无效的,而且 break 还是直接报错;
为何无法跳出
为了了解无法的原因,我们就简单手写一个 forEach 方法,来探查这个原因。
我们先来分析一下,语法和传参:
arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
- 1
- 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) } }
- 1
- 2
- 3
- 4
- 5
- 6
如你所见寥寥几句就可以实现出我们的 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)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
我们这里用了抛出异常的方式直接让回调函数报错来实现,但是还要注意一点,最好还要传入一个异常错误的 message ,我这里定为 字符串信息break,因为我们在运行时还有可能报出别的错误,有了这个标识就能识别处理哪个是正常的跳出循环,哪个是真正的执行错误。
结语
其实不仅仅是 forEach() 方法,还有一个平时经常使用的 map() 方法也是大同小异的,可以用抛出异常来实现跳出循环的操作。但我们其实也完全可以使用 some() , every() 等方法来提前验证好,或者使用 () 去检测条件捕获索引后再进行二次遍历处理。