JavaScript中有多种循环Array的方式,你是否常常分不清他们的细微差别,和适用场景。本文将详细梳理各间的优缺点,整理成表以便对比。

循环 可访问element 可访问index 可迭代property 支持中断 支持await 支持任意位置开始
for ×
for in × ×
forEach × × × ×
for of × ×

示例地址

for (ES1)

这个循环方式历史悠久,从ECMAScript 1就被支持。

const arr = ['a', 'b', 'c'];
arr.prop = 'property value'; for (let index=0; index < arr.length; index++) {
const elem = arr[index];
console.log(index, elem);
} // Output:
// 0, 'a'
// 1, 'b'
// 2, 'c'

for循环方式通用,迭代过程可以访问元素和当前元素下标索引,但是语法上略显冗长。

for in (ES1)

for in 的历史同for一样悠久。

const arr = ['a', 'b', 'c'];
arr.prop = 'property value'; for (const key in arr) {
console.log(key);
} // Output:
// '0'
// '1'
// '2'
// 'prop'

for in 用来循环数组不是一个合适的选择。

  • 迭代的是属性key,不是值
  • 由于属性 key 是字符串,迭代出的元素索引是 string,不是 number.
  • 迭代的是数组实例上所有可枚举的属性key,而不是数组内元素。

如果你想获取一个对象所有的可枚举属性(包含原型链上的),那么 for in 倒是可以胜任,若仅仅是对象自身声明的属性,那 Object.keys 更合适。

forEach (ES5)

鉴于 forfor-in 都不特别适合在 Arrays 上循环,因此在ECMAScript 5中引入了辅助方法:Array.prototype.forEach.

const arr = ['a', 'b', 'c'];
arr.prop = 'property value'; arr.forEach((elem, index) => {
console.log(elem, index);
}); // Output:
// 'a', 0
// 'b', 1
// 'c', 2

这个方法很方便,它让我们可以访问数组元素和数组元素下标,而不需要做太多的事情。箭头函数(在ES6中引入)使该方法在语法上更加优雅。

forEach 主要确定是:

  • 循环内部不支持 await 操作。
  • 即使找到你想要的元素,也无法中断循环。

要实现中断循环,可以使用同期引入的 Array.prototype.same 方法。some 循环遍历所有 Array 元素,并在其回调返回一个真值时停止。

const arr = ['red', 'green', 'blue'];
arr.some((elem, index) => {
if (index >= 2) {
return true; //结束循环
}
console.log(elem);
// 隐式返回假值 undefined,继续循环
}); // Output:
// 'red'
// 'green'

for of (ES6)

for of 是 ECMAScript 6 新引入的语法。

const arr = ['a', 'b', 'c'];
arr.prop = 'property value'; for (const elem of arr) {
console.log(elem);
}
// Output:
// 'a'
// 'b'
// 'c'

for of 很适合遍历数组:

  • 迭代所有数组元素
  • 内部支持 await,甚至是 ES2018 中引入的 for-await-of 语法
  • 可以使用 break 和 continue 跳出循环

for-of 的另一个好处是,我们不仅可以遍历数组,还可以遍历任何可迭代对象(例如map)

const myMap = new Map()
.set(false, 'no')
.set(true, 'yes')
;
for (const [key, value] of myMap) {
console.log(key, value);
} // Output:
// false, 'no'
// true, 'yes'

遍历 myMap 会生成[key, value]对,对其进行解构方便直接访问。

如果你在循环中需要感知当前元素索引,可以通过 Array 方法 entries 返回可迭代的 [index,value]对。 和map一样的解构直接访问index、value:

const arr = ['chocolate', 'vanilla', 'strawberry'];

for (const [index, value] of arr.entries()) {
console.log(index, value);
}
// Output:
// 0, 'chocolate'
// 1, 'vanilla'
// 2, 'strawberry'

循环体内 await 测试

准备如下代码用于测试循环体内 awaitgetFruit 模拟远程服务延迟返回。

const fruits = ["apple", "grape", "pear"];

const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
}; const getFruit = (fruit) => {
return sleep(2000).then((v) => fruit);
};

先看 for of, 元素之间会按预期间隔输出。

(async function(){
console.log('start');
for (fruit of fruits) {
const element = await getFruit(fruit);
console.log(element);
}
console.log('start');
})(); //3个元素 间隔2s输出
"start"
"apple"
"grape"
"pear"
"end"

再看 forEach, 注意 forEach 调用后直接返回输出 loop end, 间隔2s 后同时输出了后面结果,并没有按预期各个间隔输出。

(async function () {

  console.log("foreach loop start ....");
fruits.forEach(async value => {
const element = await getFruit(value);
console.log(element);
});
console.log("foreach loop end ...."); })(); //同时输出
foreach loop start ....
foreach loop end ....
//间隔2s 后同时输出下面3个
apple
grape
pear

示例地址

Array循环for、for in、for of、forEach各间优劣的更多相关文章

  1. JavaScript Array -->map()、filter()、reduce()、forEach()函数的使用

    题目: 1.得到 3000 到 3500 之内工资的人. 2.增加一个年龄的字段,并且计算其年龄. 3.打印出每个人的所在城市 4.计算所有人的工资的总和. 测试数据: function getDat ...

  2. 【js jQuery】map集合 循环迭代取值---以及 map、json对象、list、array循环迭代的方法和区别

    后台给前台传来一个map @ResponseBody @RequestMapping(value = "getSys") public Map<Long,String> ...

  3. PHP.34-TP框架商城应用实例-后台10-商品分类-需求分析、创建无限级商品分类,递归

    商品管理需求分析 1.实现商品无限级分类管理[类似京东三级分类] 2.添加商品时要指定商品属于一个主分类和多个扩展分类[扩展分类可以是其他主分类] 3.商品列表中可以根据分类搜索商品 a) 搜索一个分 ...

  4. php的array数组 -------方法foreach循环时候,利用数组里值的引用地址(& )从而改变数组里的值

    /* * 把每个数组值后面都加个SQL然后返回数组 * foreach循环时候,直接用引用(&)的方式就能改变之前的数组 */public function array_foreach(){ ...

  5. JAVA中的for-each循环与迭代

    在学习java中的collection时注意到,collection层次的根接口Collection实现了Iterable<T>接口(位于java.lang包中),实现这个接口允许对象成为 ...

  6. 集合框架遍历方式之——for-each循环

    从Java5起,在Java中有了for-each循环,可以用来循环遍历collection和array.Foreach循环允许你在无需保持传统for循环中的索引,或在使用iterator /ListI ...

  7. ecshop循环foreach,iteration,key,index

    转载: 最近刚接触ecshop不久,感觉是非常的强大,做商城网站,整个流程都差不多搞好了,就是支付流程要自己完善完善,不过也有不足,文章功能还不够好. 通过几天的应用,总结出了ec模版中foreach ...

  8. forEach 方法 (Array) (JavaScript)

    为数组中的每个元素执行指定操作. 语法 array1.forEach(callbackfn[, thisArg]) 参数 参数 定义 array1 必选.一个数组对象. callbackfn 必选.最 ...

  9. php学习笔记:foreach循环访问关联数组里的值

    foreach循环可以将数组里的所有值都访问到,下面我们展示下,用foreach循环访问关联数组里的值. 例如: $fruit=array('apple'=>"苹果",'ba ...

随机推荐

  1. NOIP初赛篇——01计算机常识

    发展历史 年代划分 代别 年代 逻辑(电子)元件 第一代 1946-1958 电子管 第二代 1959-1964 晶体管 第三代 1965-1970 集成电路 第四代 1971-至今 大规模.超大规模 ...

  2. git的简单使用方式(基本操作部分)

    git的简单使用方式(基本操作部分) 1.简单介绍GIT的工作流程 git一般的工作流程: 克隆git的资源作为工作目录(一般会使用命令git clone进行克隆); 在克隆的资源上对文件进行增加或者 ...

  3. Java安全之Weblogic 2016-3510 分析

    Java安全之Weblogic 2016-3510 分析 首发安全客:Java安全之Weblogic 2016-3510 分析 0x00 前言 续前面两篇文章的T3漏洞分析文章,继续来分析CVE-20 ...

  4. OSTU大津法图像分割

    OSTU图像分割 最大类间方差法,也成大津法OSTU,它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分 ...

  5. python基础学习总结

    python管理cisco设备:http://www.linuxeye.com/program/1680.html 学习:https://www.liaoxuefeng.com/wiki/001431 ...

  6. 学习rac管理

    文章转自:http://blog.itpub.net/7728585/viewspace-752185/ crsctl query crs activeversion 查看版本 ocrconfig - ...

  7. 【ORA】ORA-01078和LRM-00109 解决方法

    今天切换到asm实例的时候,发现是一个空实例,尝试启动实例,结果报错ORA-01078和LRM-00109 SQL> startupORA-01078: failure in processin ...

  8. 使用line_profiler对python代码性能进行评估优化

    性能测试的意义 在做完一个python项目之后,我们经常要考虑对软件的性能进行优化.那么我们需要一个软件优化的思路,首先我们需要明确软件本身代码以及函数的瓶颈,最理想的情况就是有这样一个工具,能够将一 ...

  9. 如何创建一个 PostgreSQL 数据库?

    PostgreSQL 官网截图 PostgreSQL 是什么? PostgreSQL 是一个功能非常强大的,历史悠久,开源的关系数据库.PostgreSQL支持大部分的SQL标准并且提供了很多其他现代 ...

  10. 利用sklearn进行字典&文本的特征提取

    写在前面 这篇博客主要内容: 应用DictVectorizer实现对类别特征进行数值化.离散化 应用CountVectorizer实现对文本特征进行数值化 特征提取API sklearn.featur ...