关于javascript:面试官问我-JS-中-foreach-能不能跳出循环

7次阅读

共计 1810 个字符,预计需要花费 5 分钟才能阅读完成。

当年糊涂无知的我被问到这个问题时,脑袋一片空白,因为我一度认为 forEach 可能只是为了不便书写所发明进去的语法糖,在业务代码中也常常应用,但没有思考过它存在的问题,本文旨在记录本人的心路历程,抛砖引玉,如果对你有所帮忙那就更好啦。

那么回到题目,首先 forEach不能应用任何伎俩跳出循环 的,为什么呢?持续往下看。

咱们晓得 forEach 接管一个函数,它个别有两个参数,第一个是循环的以后元素,第二个是该元素对应的下标,手动实现一下伪代码:

Array.prototype.myForEach = function (fn) {for (let i = 0; i < this.length; i++) {fn(this[i], i, this);
    }
}

forEach是不是真的这么实现我无从讲究,然而以上这个简略的伪代码的确满足 forEach 的个性,而且也很显著就是不能跳出循环,因为基本没有方法操作到真正的 for 循环体。

起初通过查阅文档,发现官网对 forEach 的定义基本不是我认为的语法糖,它的规范说法是 forEach 为每个数组元素执行一次 你所提供的函数。官网文档也有这么一段话:

除抛出异样之外,没有其余办法能够进行或中断循环。如果您须要这种行为,则该 forEach()办法是谬误的工具。

应用抛出异样来跳出 foreach 循环:

let arr = [0, 1, "stop", 3, 4];
try {
    arr.forEach(element => {if (element === "stop") {throw new Error("forEachBreak");
        }
        console.log(element); // 输入 0 1 前面不输入
    });
} catch (e) {console.log(e.message); // forEachBreak
};

那么可不可以认为,forEach能够跳出循环,应用抛出异样就能够了?这点我认为仁者见仁智者见智吧,在 forEach 的设计中并没有中断循环的设计,而应用 try-catch 包裹时,当 循环体过大性能会随之降落 ,这是无奈防止的,所以抛出异样能够作为一种中断forEach 的伎俩,但并不是为解决 forEach 问题而存在的银弹。

再次回归到结尾写的那段伪代码,对它进行一些优化,在真正的 for 循环中退出对传入函数的判断:

// 为防止争议此处不覆写原有 forEach 函数
Array.prototype.myForEach = function (fn) {for (let i = 0; i < this.length; i++) {let ret = fn(this[i], i, this);
        if (typeof ret !== "undefined" && (ret == null || ret == false)) break;
    }
}

这样的话就能依据 return 值来进行循环跳出啦:

let arr = [0, 1, "stop", 3, 4];

arr.myForEach(x => {if (x === 'stop') return false
    console.log(x); // 输入 0 1 前面不输入
});

// return 即为 continue:arr.myForEach(x => {if (x === 'stop') return
    console.log(x); // 0 1 3 4
});

文档中还提到 forEach须要一个同步函数 ,也就是说在应用 异步函数 Promise作为回调时会产生预期以外的后果,所以 forEach 还是须要慎用。

当然,用简略的 for 循环去实现所有事件也不失为一种方法,代码首先是写给人看的,附带在机器上运行的作用 forEach 在很多时候用起来更加棘手,但也务必在了解 JS 如何设计这些工具函数的前提下来编写咱们的业务代码。

咱们能够在遍历数组时应用 for..of..,在遍历对象时应用for..in..,而官网也在forEach 文档下列举了其它一些工具函数,这里不做过多开展:

Array.prototype.find()
Array.prototype.findIndex()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.every()
Array.prototype.some()

如何依据不同的业务场景,抉择应用对应的工具函数来更无效地解决业务逻辑,才是咱们真正应该思考的,或者这也是面试当中真正想考查的吧。

原文链接 https://juejin.cn/post/697197…

正文完
 0