菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
29
0

forEach无法跳出循环的自我理解

原创
05/13 14:22
阅读数 887

最近写代码才偶然发现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都不能终止循环~~~~

如果用到循环遍历的情况还是要慎重选择!!!!

发表评论

0/200
29 点赞
0 评论
收藏