在 JavaScript 中,for...in 和 for...of 是用于迭代对象和数组的两种不同的循环结构。
先说结论:
-
推荐在循环对象属性的时候,使用
for...in
,在遍历数组的时候的时候使用for...of
。 -
for...in
循环出的是key,for...of
循环出的是value -
注意,
for...of
是ES6新引入的特性。修复了ES5引入的for...in
的不足 -
for...of
不能循环普通的对象,需要通过和Object.keys()
搭配使用
一、for...in 循环:
- 用于迭代对象的属性名称。
- 可以用于迭代对象、数组、字符串等可迭代对象的属性。
- 循环的是对象的键(或索引),而不是值。
- 注意:`for...in` 循环会枚举对象的所有可枚举属性,包括原型链上的属性。
const obj = {a: 1, b: 2, c: 3};for (const key in obj) {console.log(key); // 输出:a, b, c
}// 当然,也可遍历数组,只是不推荐这么使用
let aArray = ['a',123,{a:'1',b:'2'}]
for(let index in aArray){console.log(`${aArray[index]}`); // 'a',123,{a:'1',b:'2'}
}
二、for...of 循环:
- 用于迭代可迭代对象的值。
- 不能直接用于迭代普通对象,因为普通对象不是可迭代对象。
- 可以用于迭代数组、字符串、Map、Set 等实现了迭代器接口的对象。
- 循环的是对象的值,而不是键(或索引)。
const arr = [1, 2, 3];for (const value of arr) {console.log(value); // 输出:1, 2, 3
}
三、 for in 和 for of 的最大区别
参考MDN MDN关于for of的解释
for...of语句在可迭代对象(包括 Array, Map, Set, String, TypedArray,arguments 对象等等)上创建一个迭代循环,对每个不同属性的属性值,调用一个自定义的有执行语句的迭代挂钩.
也就是说,for of只可以循环可迭代对象的可迭代属性,不可迭代属性在循环中被忽略了。
并且给与了一个对比的例子
Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};let iterable = [3, 5, 7];
iterable.foo = "hello";for (let i in iterable) {console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}for (let i of iterable) {console.log(i); // logs 3, 5, 7
}
我们可以看到,对于array的不可迭代元属性objCustom、arrCustom和实例属性foo,在循环中都被忽略
这是for in迭代KEY,for of迭代value之外最大的区别
通常情况下,如果你需要迭代对象的属性名称,就使用 `for...in` 循环;如果你需要迭代可迭代对象的值,就使用 `for...of` 循环。