for...in和for...of的介绍及区别
for...in
以任意顺序遍历一个对象自有的、继承的、可枚举[1]的、非Symbol的属性。对于每个不同的属性,语句都会被执行(MDN)
简单来说下图:就是for...in
是无序遍历,有可能遍历数组的时候,不能保证顺序是正常的取出来。所以不推荐用for...in遍历数组类型值。
for...in循环有几个缺点[2]
-
数组的键名是数字,但是 for...in
循环是以字符串作为键名"0"、"1"、"2"等等。 -
for...in
循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 -
某些情况下, for...in
循环会以任意顺序遍历键名。 -
for...in
循环只能获得对象的键名,不能直接获取键值
尽量不要用for in遍历数组
集合遍历的效率为:hash
> for(;;)
> for...in
集合相关操作首选对象,次之用for循环遍历。
for...of
for...of
是遍历所有数据结构的统一的方法,但是只能遍历具有iterator
迭代接口的值。因for...of循环内部调用的是数据结构的Symbol.iterator
方法。
for...of循环可以使用的范围包括:
数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。
原生Object没有这个接口,默认是不能用for...of
进行遍历的,会报错:
不同点
-
for...in
可以遍历对象,for...of
不可以; -
for...in
循环读取键名,for...of
循环读取键值; -
for...in
不适用于遍历数组,原因如下一条。 -
for...of
循环调用遍历器接口,这一点跟for...in循环也不一样。所以遍历数字集合的数组时,for...in返回字符串,for...of返回的是数字。
-
let arr = [3, 5];
for (let i in arr) {
console.log(i); // 字符串类型的键名:'0', '1'
}
for (let i of arr) {
console.log(i); // 数字类型的值:3, 5
}
性能比较:
for
/while
> forEach
等(函数式编程+for) > for...of
> for...in
参考资料
可枚举的: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
[2]es6文档关于for...in相关知识: https://es6.ruanyifeng.com/#docs/iterator#for---of-%E5%BE%AA%E7%8E%AF
让我们一起携手同走前端路!
关注公众号回复【加群】即可
评论