「译」forEach循环中你不知道的3件事

前言 本文925字,阅读大约需要7分钟。 总括: forEach循环中你不知道的3件事。 原文地址:3 things you didn’t know about the forEach loop in JS 公众号:「前端进阶学习」,回复「666」,获取一揽子前端技术书籍 自弃者扶不起,自强者击不倒。 正文 你觉得你真的学会用forEach了么? 这是我之前对forEach循环的理解:就是一个普通语义化之后的for循环,可以被break,continue,return。 这篇文章将向你展示forEach中你可能不了解的3件事。 1. return不会停止循环 你觉得下面的代码在打印1和2之后会停止么? array = [1, 2, 3, 4]; array.forEach(function (element) { console.log(element); if (element === 2) return; }); // Output: 1 2 3 4 答案是不会,上述代码会正常打印1,2,3,4。如果你有Java背景,你也许会很诧异,这怎么可能呢? 原因是我们在forEach函数中传了一个回调函数,该回调函数的行为和普通函数一样,我们return操作其实就是普通函数中return。所以并不符合我们预期将forEach循环打断。 MDN官方文档: 注意: 除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。 我们将上述代码改写: const array = [1, 2, 3, 4]; const callback = function(element) { console.log(element); if (element === 2) return; // would this make a difference? no. } for (let i = 0; i < array.length; i++) { callback(array[i]); } // Output: 1 2 3 4 这就是上述代码实际的执行思路,return操作只作用于当前的函数,自然不会对for循环产生影响 2. 不能break 下面的代码你觉得会被break掉么? const array = [1, 2, 3, 4]; array.forEach(function(element) { console.log(element); if (element === 2) break; }); // Output: Uncaught SyntaxError: Illegal break statement 不会,甚至这行代码都不会运行,直接报错了。 那么这段代码如何达到我们原本想达到的效果呢? 用普通for循环就好了: const array = [1, 2, 3, 4]; for (let i = 0; i < array.length; i++) { console.log(array[i]); if (array[i] === 2) break; } // Output: 1 2 3. 不能continue 下面代码会是跳过2只打印1、3、4吗? const array = [1, 2, 3, 4]; array.forEach(function (element) { if (element === 2) continue; console.log(element); }); // Output: Uncaught SyntaxError: Illegal continue statement: no surrounding iteration statement 同样不会,和break一样,报错,这行代码之后甚至都不会运行。 怎么达到预期呢? 还是使用普通的for循环来解决: for (let i = 0; i < array.length; i++) { if (array[i] === 2) continue; console.log(array[i]); } // Output: 1 3 4 译者补充 forEach函数的实际运行原理其实是这样的,伪代码如下: let arr = [1, 2]; arr.forEach(function(ele) { console.log(ele); }); // output: 1, 2 // 上面代码等同于 function func(ele) { console.log(ele); } for (let i = 0; i < arr.length; i++) { func(arr[i]) } // output: 1, 2 实际上forEach的polyfill实现也是这样的,在forEach函数中执行一个for循环,在for循环里调用回调函数。 因此,像下面代码自然不会符合预期: let arr = [1, 2]; let sum = 0; function add(a) { return a; } arr.forEach(async function(ele) { sum += await add(ele); }); console.log(sum); // Output:0 改写如下: let arr = [1, 2]; let sum = 0; function add(a) { return a; } for (let i = 0; i < arr.length; i++) { sum += await add(arr[i]); } console.log(sum); // Output:3 订阅更多文章可关注「前端进阶学习」,回复「666」,获取一揽子前端技术书籍 前端进阶学习

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):