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. PHP 自定义 alert 跳转方法

    /** * 跳转方法 * @param $msg * @param null $path * @param null $parent */ public function alert($msg,$pa ...

  2. JavaScript DOM编程艺术(第2版)的简单总结

    介绍 JavaScript DOM编程艺术(第2版)主要讲述了 JavaScript.DOM 和 HTML5 的基础知识,着重讲述了 DOM 编程,并通过几个实例演示了具有专业水准的网页开发. 下面介 ...

  3. ssh信任 sftp用法 scp用法【转】

    为了进行批量关机工作,前提要配置好ssh的双机信任. A机192.168.1.241 B机192.168.1.212 在A机上获取一个pub密钥,即为公共密钥. 执行这个命令后:ssh-keygen  ...

  4. Redis 设计与实现 10:五大数据类型之有序集合

    有序集合 sorted set (下面我们叫zset 吧) 有两种编码方式:压缩列表 ziplist 和跳表 skiplist. 编码一:ziplist zset 在 ziplist 中,成员(mem ...

  5. Docker学习笔记之创建Ubuntu基础镜像

    在创建基础镜像之前需要安装Bootstrap工具debootstrap,所以执行命令: sudo apt install debootstrap 软件安装完成后就可以使用debootstrap工具下载 ...

  6. List使用Stream流进行集合Collection的各种运算汇总:对BigDecimal求和,某个字段的和、最大值、最小值、平均值,字段去重,过滤等

    写Java接口的朋友都知道,Java 8的更新,经常会用到过滤 list<Object> 里的数据,本文就对List使用Stream流进行集合Collection的各种运算做一个汇总! 优 ...

  7. Oracle Rac to Rac One Node

    =~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2020.01.14 20:05:12 =~=~=~=~=~=~=~=~=~=~=~= [oracle@rac01 ~]$ srvc ...

  8. Docker-常用基建的安装与部署

    一:Docker安装 1:通过yum安装docker yum -y install gcc yum -y install gcc-c++ yum remove docker \ docker-clie ...

  9. [XAML] 使用 XAML 格式化工具:XAML Styler

    1. XAML 的问题 刚入门 WPF/UWP 之类的 XAML 平台,首先会接触到 XAML 这一新事物.初学 XAML 时对它的印象可以归纳为一个词:一坨. 随着我在 XAML 平台上工作的时间越 ...

  10. SAP系统跨平台字符编码转换

    SAP系统在进行了夸平台的迁移,可能会遇到操作系统层文件编码不同,导致SAP系统无法识别或者乱码的问题.例如SAP系统从AIX平台迁移到linux平台,SAP应用服务器的编码会发生变化,从4102变化 ...