Array循环for、for in、for of、forEach各间优劣
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)
鉴于 for
和 for-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 测试
准备如下代码用于测试循环体内 await
,getFruit
模拟远程服务延迟返回。
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各间优劣的更多相关文章
- JavaScript Array -->map()、filter()、reduce()、forEach()函数的使用
题目: 1.得到 3000 到 3500 之内工资的人. 2.增加一个年龄的字段,并且计算其年龄. 3.打印出每个人的所在城市 4.计算所有人的工资的总和. 测试数据: function getDat ...
- 【js jQuery】map集合 循环迭代取值---以及 map、json对象、list、array循环迭代的方法和区别
后台给前台传来一个map @ResponseBody @RequestMapping(value = "getSys") public Map<Long,String> ...
- PHP.34-TP框架商城应用实例-后台10-商品分类-需求分析、创建无限级商品分类,递归
商品管理需求分析 1.实现商品无限级分类管理[类似京东三级分类] 2.添加商品时要指定商品属于一个主分类和多个扩展分类[扩展分类可以是其他主分类] 3.商品列表中可以根据分类搜索商品 a) 搜索一个分 ...
- php的array数组 -------方法foreach循环时候,利用数组里值的引用地址(& )从而改变数组里的值
/* * 把每个数组值后面都加个SQL然后返回数组 * foreach循环时候,直接用引用(&)的方式就能改变之前的数组 */public function array_foreach(){ ...
- JAVA中的for-each循环与迭代
在学习java中的collection时注意到,collection层次的根接口Collection实现了Iterable<T>接口(位于java.lang包中),实现这个接口允许对象成为 ...
- 集合框架遍历方式之——for-each循环
从Java5起,在Java中有了for-each循环,可以用来循环遍历collection和array.Foreach循环允许你在无需保持传统for循环中的索引,或在使用iterator /ListI ...
- ecshop循环foreach,iteration,key,index
转载: 最近刚接触ecshop不久,感觉是非常的强大,做商城网站,整个流程都差不多搞好了,就是支付流程要自己完善完善,不过也有不足,文章功能还不够好. 通过几天的应用,总结出了ec模版中foreach ...
- forEach 方法 (Array) (JavaScript)
为数组中的每个元素执行指定操作. 语法 array1.forEach(callbackfn[, thisArg]) 参数 参数 定义 array1 必选.一个数组对象. callbackfn 必选.最 ...
- php学习笔记:foreach循环访问关联数组里的值
foreach循环可以将数组里的所有值都访问到,下面我们展示下,用foreach循环访问关联数组里的值. 例如: $fruit=array('apple'=>"苹果",'ba ...
随机推荐
- 五、Zookeeper、Hbase集群搭建
一.前提 1.安装JDK 2.安装Hadoop 3.安装zoookeeper 1.加入zookeeper包,并解压tar -zxvf zookeeper-3.4.9.tar.gz 2.去/etc/pr ...
- Databricks 第6篇:Spark SQL 维护数据库和表
Spark SQL 表的命名方式是db_name.table_name,只有数据库名称和数据表名称.如果没有指定db_name而直接引用table_name,实际上是引用default 数据库下的表. ...
- Flutter 基础组件:进度指示器
前言 Material 组件库中提供了两种进度指示器:LinearProgressIndicator和CircularProgressIndicator,它们都可以同时用于精确的进度指示和模糊的进度指 ...
- python学习笔记 | 列表去重
''' @author: 人人都爱小雀斑 @time: 2020/3/10 10:29 @desc: ''' L=[1,5,7,4,6,3,0,5,8,4,4] 方法1:for循环 L1=[] for ...
- spring cloud gateway 日志打印
从api请求中获取访问的具体信息,是一个很常见的功能,这几天在研究springcloud,使用到了其中的gateway,刚好将研究的过程结果都记录下来 0. Version <parent> ...
- 【Linux】rsync的相关用途
Rsync,代表"remote sync",它是本地和远程主机文件同步工具.它只同步更改的文件,以此实现最小化传输数据. 我使用Ubuntu 16.04做为例子,但是你可以把它应用 ...
- vue路由切换和用location切换url的区别
最近的业务涉及到了axios的拦截器,要在request.js里面要根据状态码来跳转页面,这时候我就面对了几种跳转选择: 1.使用location.href='/url'来跳转,简单方便,但是刷新了页 ...
- 09--Docker 安装tomcat9
1.在hub.docker.com中获取tomcat拉取地址 docker pull tomcat:9.0.41-jdk8-corretto 2.查看Dockerfile 中WORKDIR 为/use ...
- centos7.4使用filrewalld打开关闭防火墙与端口
1.firewalld的基本使用启动: systemctl start firewalld关闭: systemctl stop firewalld查看状态: systemctl status fire ...
- 通过js给某个标签添加内容或者删除标签
添加内容 //先保存div中原来的html var tag = document.getElementById("tag").innerHTML; //构造新的内容 var cou ...