【快速入门系列】简述 for...in 和 for...of 区别

news/2024/5/15 5:23:59

引言

在对数组或对象进行遍历时,我们经常会使用到两种方法:for...infor...of,那么这两种方法之间的区别是什么呢?让我们来研究研究。

一、for...in

首先我们看下MDN对for...in方法的解释:for...in | MDN

for...in 循环只遍历可枚举属性。像 Array和 Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性,例如 String 的 indexOf() 方法或 Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。

首先,我们简单的使用for...in分别对对象和数组进行遍历:

// 遍历对象
let obj = {a: 1,b: 2,c: 3
};
for(let item in obj) {console.log("item:" + item);console.log(obj[item]);
}// 运行结果
item:a
1
item:b
2
item:c
3
// 遍历数组
let arr = [1, 2, 3];
for(let item in arr) {console.log("item:" + item);console.log(arr[item]);
}// 运行结果
item:0
1
item:1
2
item:2
3

我们发现,使用for...in进行遍历时,item值为对象的key,为数组的index。
我们知道,数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同,因此不能保证for...in以某种固定的顺序返回索引,因此,不推荐使用for...in进行数组的遍历

下面,我们在上面代码的基础上,在arr数组上增加一个自定义属性,再次遍历,查看结果。

arr.name = 'arrName';
for(let item in arr) {console.log("item:" + item);console.log(arr[item]);
}// 运行结果
item:0
1
item:1
2
item:2
3
item:name
arrName

我们发现,for...in不仅会遍历数组中的元素,还会遍历自定义属性

二、for...of

说完for...in我们再来看看for...of,我们还是先来看看MDN对其的解释 for...of | MDN

for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。

同样的,我们还是使用与for...in相同的代码进行测试

// 遍历对象
let obj = {a: 1,b: 2,c: 3
};
for(let item of obj) {console.log("item:" + item);console.log(obj[item]);
}// 运行结果
for(let item of obj) {^TypeError: obj is not iterable
...
// 遍历数组
let arr = [1, 2, 3];
for(let item of arr) {console.log("item:" + item);console.log(arr[item]);
}// 运行结果
item:1
undefined
item:2
undefined
item:3
undefined

我们可以看出,使用for...of对对象进行遍历时,报了TypeError: obj is not iterable错误,对数组进行遍历时,item直接是数组每一项的值

我们再为arr增加自定义属性,查看效果。

arr.name = 'arrName';
for(let item in arr) {console.log("item:" + item);console.log(arr[item]);
}// 运行结果
item:1
undefined
item:2
undefined
item:3
undefined

for...of没有对数组的自定义属性进行遍历

三、总结

根据以上测试结果并参考了相关资料,我们得出了以下结论:

  1. 遍历对象时推荐使用for...in,其中item为对象的key。使用for...of会报错。
  2. 遍历数组时推荐使用for...of,其中item为数组每一项的值。使用for...in则不能保证遍历顺序且会遍历出自定义属性。
  3. for...in是ES5特性,for...of是ES6特性,因此需要注意兼容性。
  4. 如果要使用for...of遍历普通对象,需要配合Object.keys()一起使用。

结束语

以上内容是我们对for...infor...of的测试对比,在使用时记住其区别可更快的编写代码和排查错误,若想了解其更深层区别,建议认真阅读MDN相关资料。


http://lihuaxi.xjx100.cn/news/236959.html

相关文章

你关注区块链了吗?

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 前言:关于什么是区块链的论述有很多,本文从公共数据库、印刷机、治理、经济学、组织方式等方面进行阐述,作者观点…

高频数据交换下Flutter与ReactNative的对比

后端使用go写的socketio服务模拟期货行情数据,每10ms推送10条行情数据 ReactNative已经尽力优化了。 Flutter由于没flutter-socketio这个库不支持dart2.0以上的版本,所有用了安卓的socketio,通过事件与Flutter通讯。 1.内存占用 ReactNative …

linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结

2)对于.gz结尾的文件 gzip -d all.gz gunzip all.gz转载于:https://blog.51cto.com/13203181/2115527

你不应该关注区块链的“杀手级应用”

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 在每一次区块链大会上,人们无不讨论一个话题:区块链的下一个杀手级应用是什么?下一个获得大规模应用的成功案例是…

java并发编程——并发容器类介绍

2019独角兽企业重金招聘Python工程师标准>>> 并发容器的简单介绍 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能。因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性&a…

洛谷 P1816 忠诚

题目描述 老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一…

区块链技术之以太坊ETH白皮书

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 基于中本聪区块链比特币1.0之后,天才少年Vitalik Buterin(V神)在2013年年末发布了以太坊白皮书,其实…

hadoop生态搭建(3节点)-06.hbase配置

# http://archive.apache.org/dist/hbase/1.2.4/ # 安装 hbase tar -zxvf ~/hbase-1.2.4-bin.tar.gz -C /usr/local rm –r ~/hbase-1.2.4-bin.tar.gz # 配置环境变量# node1 node2 node3 vi /etc/profile# 在export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL下添…