最近写代码才偶然发现forEach无法用return跳出循环,有朋友说用break可以跳出,感觉这个解决方案很瞎,试了试确实很瞎!首先break是用在循环体中的,forEach虽然是循环,但是代码写在回调函数里,这一点就直接决定forEach不能使用break。
let arr=[0,1,2,3,4,5];
//示例1:
arr.forEach(v=>{
console.log(v);//输出结果:0,1,2,3,4,5
if(v>3){
return;
}
})
//示例2:
arr.forEach(v=>{
if(v<3){
reutrn;
}
console.log(v);//输出结果:3,4,5
})
//示例3:
arr.forEach(v=>{
if(v>3){
return;
}
console.log(v);//输出结果:0,1,2,3
})
上面前两个示例可以很直观的看出return并没有跳出循环,而示例3看似输出到3后就在停止循环了,其实输出到三后也并没有结束循环,只是结束了当前的回调函数!根据不同的例子,我的理解是:forEach其实是一个循环体,和一个函数体的结合,循环体包裹着函数体,所以return只是跳出了函数体,但是并没有跳出循环体。
查看MDN中Array.prototype.forEach()对forEach方法的解释:
forEach()方法对数组的每个元素执行一次提供的函数。
根据MDN中Polyfill板块中我们可以看到forEach()的实现原理callback在最内层,while是循环体包裹着callback!综上应该可以搞明白为啥forEach不能用return跳出循环啦!
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
//forEach原理看这!!!
}
k++;
}
};
}
搞明白了forEach无法跳出循环,那么当需要跳出循环的时候,我们应该怎么办呢?查看MDN,它为我们提供了下面的方法。
- for循环
- Array.prototype.every()
- Array.prototype.some()
- Array.prototype.find()
我测试了上面的几种方法,还是发现了一些很有意思的情况~~~~
let arr=[0,1,2,3,4,5];
let result1=arr.some(v=>v<3);
let result2=arr.find(v=>v<3);
let result3=arr.every(v=>v<3);
console.log(`some:${result1},find:${result2},every:${result3}`);
//输出结果:some:true,find:0,every:false
every()是对数组中每一项运行给定函数,如果该函数对每一项返回true,则返回true。
find()是对数组中每一项运行给定函数,发现满足条件的函数即刻返回,不在执行后面函数。
some()是对数组中每一项运行给定函数,如果该函数对任一项返回true,则返回true。
arr.forEach(v=>{
console.log(v);//输出结果:0,1,2,3,4,5
if(v>2){
return;
}
})
console.log("---------------");
arr.some(v=>{
console.log(v);//输出结果:0,1,2,3
if(v>2){
return true;
}
})
console.log("---------------");
arr.find(v=>{
console.log(v);//输出结果:0,1,2,3
if(v>2){
return true;
}
})
console.log("---------------");
arr.every(v=>{
console.log(v);//输出结果:0
if(v>2){
return;
}
})
//some(callback)和find(callback)方法中,如果callback函数体内的return~~~~后面不跟值,或者return后跟的是false都不能终止循环~~~~
如果用到循环遍历的情况还是要慎重选择!!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。