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

让我们一起携手同走前端路!
关注公众号回复【加群】即可
      评论
