首先,一句话概括:for in是遍历(object)键名,for of是遍历(array)键值。
for...in
for...in 循环只遍历可枚举属性(包括它的原型链上的可枚举属性)。像 Array和Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性,例如 String 的 indexOf() 方法或 Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
var obj = {a:1, b:2, c:3}; for (let key in obj) { console.log(key); } // a // b // c
for...of
for...of语句在可迭代对象(包括Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
const array1 = ['a', 'b', 'c']; for (const val of array1) { console.log(val); } // a // b // c
for of不可以遍历普通对象,想要遍历对象的属性,可以用for in循环, 或内建的Object.keys()方法
for...of与for...in的区别
无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。
for...in语句以任意顺序迭代对象的可枚举属性。
for...of 语句遍历可迭代对象定义要迭代的数据。
再举个例子,如下:
①遍历数组
const arr1 = ['a', 'b', 'c']; for (let i in arr1) { console.log(i) // 0, 1, 2 } const arr2 = ['a', 'b', 'c']; for (let i of arr2) { console.log(i) // a, b, c }
for in 返回数组的下标(key);
for of 返回数组的元素;
②给数组手动添加属性
const arr3 = ['a', 'b']; arr3.name = 'c'; for (let i in arr3) { console.log(i) // 0, 1, name }
for in 循环可以遍历出name这个键名
③遍历对象
const json = {"a": 1, "b": 2, "c": 3}; for (let i in json) { console.log(i) // a, b, c } for (let i of json) { console.log(i) }
for in遍历获取对象key值;
for of 报错;
总结:
- for..of适用遍历数/数组对象/字符串/map/set等拥有迭代器对象的集合.但是不能遍历对象,因为没有迭代器对象.与forEach()不同的是,它可以正确响应break、continue和return语句
- for-of循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用for-in循环(这也是它的本职工作)或内建的Object.keys()方法:
- 遍历对象时推荐使用for...in,其中item为对象的key。使用for...of会报错。
- 遍历数组时推荐使用for...of,其中item为数组每一项的值。使用for...in则不能保证遍历顺序且会遍历出自定义属性。
- for...in是ES5特性,for...of是ES6特性,因此需要注意兼容性。
- 如果要使用for...of遍历普通对象,需要配合Object.keys()一起使用。