「译」foreach循环中你不知道的3件事(代码片段)

秦至 秦至     2022-12-24     604

关键词:

前言

本文925字,阅读大约需要7分钟。

总括: forEach循环中你不知道的3件事。

自弃者扶不起,自强者击不倒。

正文

你觉得你真的学会用forEach了么?

这是我之前对forEach循环的理解:就是一个普通语义化之后的for循环,可以被break,continue,return

这篇文章将向你展示forEach中你可能不了解的3件事。

1. return不会停止循环

你觉得下面的代码在打印12之后会停止么?

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」,获取一揽子前端技术书籍

技术图片

js中你不知道的一些概念知识(代码片段)

DOM元素e的e.getAttribute(propName)和e.propName有什么区别和联系e.getAttribute(),是标准DOM操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性e.propName通常是在HTML文档中访问特定元素的... 查看详情

[译]关于python中的数字你可能不知道的3件事

...hon中的数字不仅仅是它们的原始值。让我们看看你可能不知道的关于Python中数字的三件事。1.数字有方法Python中有个概念叫做:一切皆对象。您在Python中学习的第一个对象​​"HelloWorld"​​是表示字符串的​​str​​对象。然后... 查看详情

php代码审计中你不知道的牛叉技术点

一、前言php代码审计如字面意思,对php源代码进行审查,理解代码的逻辑,发现其中的安全漏洞。如审计代码中是否存在sql注入,则检查代码中sql语句到数据库的传输和调用过程。入门php代码审计实际并无什么门槛要求,只需要... 查看详情

说说java中你不知道switch关键字的奥秘(代码片段)

Switch语法switch作为Java内置关键字,却在项目中真正使用的比较少。关于switch,还是有那么一些奥秘的。要什么switch,我有if-else确实,项目中使用switch比较少的一个主要原因就在于它的作用能被if-else代替,况且switch对类型的限制... 查看详情

vue中你不知道但却很实用的黑科技(代码片段)

最近数月一直投身于iView的开源工作中,完成了大大小小30多个UI组件,在Vue组件化开发中积累了不少经验。其中也有很多带有技巧性和黑科技的组件,这些特性有的是Vue文档中提到但却容易被忽略的,有的更是没有写在文档里,... 查看详情

asp.netcore中间件应用实践中你不知道的那些事(代码片段)

一、概述这篇文章主要分享Endpoint终结点路由的中间件的应用场景及实践案例,不讲述其工作原理,如果需要了解工作原理的同学,可以点击查看以下两篇解读文章:Asp.NetCoreEndPoint终结点路由工作原理解读ASP.NETCORE管道模型及中... 查看详情

记录--你不知道的foreach函数(代码片段)

...出来的一些知识,希望对大家有所帮助老实说我不喜欢用forEach,因为它导致的一些bug总是这么不经意,盘点我不喜欢的原因原因一:不支持处理异步函数先看一个例子:asyncfunctiontest()letarr=[3,2,1]arr.forEach(asyncitem=>constres=awaitmock... 查看详情

你不知道的foreach(javascript)(代码片段)

...间传达一种可落地的编程思想或解决方案。Array.prototype.forEach(callbackfn[,thisArg])规范地址(下述引用文,均源自该规范):https://tc39.es/ecma262/#sec-array.prototype.foreach跳过不存在的元素callbackfn只对数组中实际存在的元... 查看详情

你不知道的foreach(javascript)(代码片段)

...间传达一种可落地的编程思想或解决方案。Array.prototype.forEach(callbackfn[,thisArg])规范地址(下述引用文,均源自该规范):https://tc39.es/ecma262/#sec-array.prototype.foreach跳过不存在的元素c 查看详情

关于linux之父,你不知道的6件事(代码片段)

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇如果让你现在说出三个程序员的名字,Linus很可能就在其中。作为世界上最著名的电脑程序员、黑客之一,LinusBenedictTorvalds写出了Linux内核1.0版&... 查看详情

javascript中你不知道的5个json-使用技巧(代码片段)

开发中,经常使用 JSON.stringify(object) 来序列化对象,但除了第一个参数外,还有其它参数可用...格式化//默认的JSON.stringify(object)出来数据是一行字符串constuser=name:'JackieDYH',age:30,isAdmin:true,friends:['小可爱... 查看详情

关于java你不知道的10件事

作为Java书呆子,比起实用技能,我们会对介绍Java和JVM的概念细节更感兴趣。因此我想推荐 LukasEder在 jooq.org 发表的原创作品给大家。你是从很早开始就一直使用Java吗?那你还记得它的过去吗?那时,Java还叫Oak,OO还... 查看详情

关于java你不知道的10件事

作为Java书呆子,比起实用技能,我们会对介绍Java和JVM的概念细节更感兴趣。因此我想推荐LukasEder在jooq.org发表的原创作品给大家。 你是从很早开始就一直使用Java吗?那你还记得它的过去吗?那时,Java还叫Oak,OO还是一个热... 查看详情

我怎样才能缩短“foreach”以便它只显示 3 件事?

】我怎样才能缩短“foreach”以便它只显示3件事?【英文标题】:Howcanishorta"foreach"soitdisplayonly3things?【发布时间】:2013-05-0702:07:07【问题描述】:我试图从我的数据库中仅显示3个视频(第2个、第3个和第4个),但我真的... 查看详情

关于azuresql数据库你不知道的5件事

点击上方蓝字关注“汪宇杰博客”原文:AzureTipsandTricks翻译:汪宇杰AzureSQLDatabase如果您喜欢SQLServer,那么您可能也喜欢AzureSQL数据库。AzureSQL数据库是Azure中的SQLServer即服务。你负责处理数据,Azure负责运行和保护... 查看详情

将 foreach 循环更改为 Parallel.ForEach 循环

】将foreach循环更改为Parallel.ForEach循环【英文标题】:ChangingaforeachlooptoaParallel.ForEachloop【发布时间】:2012-01-0306:41:33【问题描述】:好的,这里是基本背景。该程序连接到Outlook/Exchange并解析所有邮件消息以查看哪些是加密的。... 查看详情

return跳不出foreach循环(代码片段)

vararr=[1,1,2,2,3];arr.forEach(item=>console.log(item);if(item==2||item==3)returnfalse;);简单的一个代码,你以为会输出什么?是1,1,2?然后却是1,1,2,2,3不管是return还是returnfalse都不能跳出forEach循环,所以来看下forEach定义:看到没,这个方法... 查看详情

译做好这几件事,代码质量可以提升一个档次

这篇文章又是关于代码质量的,有些同学可能觉得我比较啰嗦。不过我就是想用这种方式让大家重视起来。其实说来说去就那么几种方法,但是实际执行起来真是难于登天。低质量的代码真的是一种灾难。当你的代码变得越来越... 查看详情