「译」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循环打断。
注意: 除了抛出异常以外,没有办法中止或跳出
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」,获取一揽子前端技术书籍

「译」forEach循环中你不知道的3件事的更多相关文章
- 「译」 .NET 6 中 gRPC 的新功能
gRPC是一个现代的.跨平台的.高性能的 RPC 框架.gRPC for .NET 构建在 ASP.NET Core 之上,是我们推荐的在 .NET 中构建 RPC 服务的方法. .NET 6 进一步 ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- 「译」JavaScript 的怪癖 1:隐式类型转换
原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...
- jvm系列(十):如何优化Java GC「译」
本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...
- jvm系列(七):如何优化Java GC「译」
本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...
- iOS 9,为前端世界都带来了些什么?「译」 - 高棋的博客
2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...
- C#在foreach循环中修改字典等集合出错的处理
C#在foreach循环中修改字典等集合出错:System.InvalidOperationException: Collection was modified; enumeration operat ...
- C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响)
C#不允许在foreach循环中改变数组或集合中元素的值(注:成员的值不受影响),如以下代码将无法通过编译. foreach (int x in myArray) { x++; //错误代码,因为改变 ...
随机推荐
- IDEA 设置 自动编译
转载自:https://www.cnblogs.com/eyesfree/p/9321795.html 设置 File ->Setting ->Compile: 勾选"Make ...
- elasticsearch数据组织结构
elasticsearch数据组织结构 1. mapping 1.1. 简介 mapping:意为映射关系,特别是指组织结构.在此语境中可理解为数据结构,包括表结构,表约束,数据类型等 ...
- linux的数据盘挂载
图文教程: Linux的云服务器数据盘未做分区和格式化,可以根据以下步骤进行分区以及格式化操作. 一:登陆 用Linux 的SSH 登陆软件(xshell 或者putty) 登陆阿里云主机服务器. 二 ...
- map或者对象转换
map或者对象转换为具有相同字段的对象 List<Example> errorCodeExcelBeanList = JSONObject.parseArray(((JSONObject) ...
- 从蜘蛛侠到仙剑,为何知名IP都要开发VR游戏?
去年3月底斯皮尔伯格指导的<头号玩家>上映,为全球玩家和影迷塑造出一个庞大.刺激而又真实无比的虚拟游戏世界--"绿洲".电影上映后,在人们感叹斯皮尔伯格旺盛的艺术想象力 ...
- python字典操作方法详解
前言 字典是一种通过名字或者关键字引用的得数据结构,key 类型需要时被哈希,其键可以是数字.字符串.元组,这种结构类型也称之为映射.字典类型是Python中唯一內建的映射类型. 注意,浮点数比较很不 ...
- Python 之并发编程之线程上
一.线程概念 进程是资源分配的最小单位 线程是计算机中调度的最小单位 多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间内有多条流水线,都 ...
- jackson处理日期异常
原 jackson处理日期异常 2018年01月09日 10:50:19 阅读数:70 1.异常信息 2.原因 默认情况下,fasterxml json只支持几种format,但是肯定不支持" ...
- ZOJ4102 Array in the Pocket(2019浙江省赛)
贪心~ #include<bits/stdc++.h> using namespace std; ; int a[maxn]; int b[maxn]; int vis[maxn]; se ...
- PAT A1151 LCA in Binary Tree
利用树的前序和中序递归判定最小公共祖先~ 直接根据两个序列递归处理~ #include<bits/stdc++.h> using namespace std; ; int N,M; int ...