for in和 for of 的区别

for in 通常用于遍历对象

for of 通常用于遍历数组(ES6新增)

遍历数组

for in 遍历

const arr1 = ['a', 'b', 'c'];
for (let i in arr1) {
  console.log(i)  // 0, 1, 2
}

遍历结果为数组下标(key),并不是数组内容,并且key为字符串类型,不能直接运算

const arr3 = ['a', 'b'];
Array.prototype.method=function(){
  console.log(this.length);
}
arr3.name = 'c';
for (let i in arr3) {
  console.log(i) // 0, 1, name, method
}

使用for in会遍历数组所有的可枚举属性,包括原型。例如上面的原型方法method和name属性

for of遍历

const arr3 = ['a', 'b'];
Array.prototype.method=function(){
  console.log(this.length);
}
arr3.name = 'c';
for (let i in arr3) {
  console.log(i) // a, b
}

for of 遍历结果为数组的内容,且遍历不到原型里的方法和属性

遍历对象

for in 遍历

Object.prototype.method = function () {
  console.log(this);
}
var myObject = {
  a: 1,
  b: 2,
  c: 3
}
myObject.name = 'aa'
for (let key in myObject) {
  console.log(key); // a, b, c, name, method 
}

for in 遍历的结果为对象的键值(key),也可以遍历出原型方法和属性

在vue中可以用 v-for=”(value, key) in items” ,来获取key和value

或者 v-for=”(value, key, index) in items” ,来获取key,value和index

for of 遍历对象会报错

我也想让对象可以使用 for of循环怎么办?使用 Object.keys() 获取对象的 key值集合后,再使用 for of

const obj = {a: 'x', b: 'y'};
for (let i of Object.keys(obj)) {
  console.log(i) // a, b
}

也可以给一个对象部署 Symbol.iterator属性

总结

for in 的特点
for … in 循环返回的值都是数据结构的 键值名。
遍历对象返回的对象的key值;
遍历数组返回的数组的下标(key)。

for … in 循环不仅可以遍历数字键名,还会遍历原型上的key值和手动添加的其他键;

特别情况下, for … in 循环会以任意的顺序遍历键名

总结一句: for in 循环特别适合遍历对象


for of 特点
for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名

一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

例3这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报json is not iterable

for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。

提供了遍历所有数据结构的统一接口;


哪些数据结构部署了 Symbol.iteratoer属性了呢?
只要有 iterator 接口的数据结构,都可以使用 for of循环。

数组 Array
Map
Set
String
arguments对象
Nodelist对象, 就是获取的dom列表集合
以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(…)、和解构赋值等操作。