for...in 和 for...of 是 JavaScript 中用于遍历不同数据结构的两种循环语句,它们之间存在一些关键的区别:
1. 遍历的数据类型
for...in:主要用于遍历对象的可枚举属性(包括原型链上的属性,除非使用hasOwnProperty()方法进行过滤)。它不适用于遍历数组,因为会返回数组索引(字符串类型的键)而不是数组元素的值。for...of:用于遍历可迭代对象(如数组、Map、Set、String、TypedArray、NodeList等)的值。它返回的是迭代器提供的值,对于数组来说,就是数组元素的值。
2. 使用场景
for...in:当你需要遍历一个对象的所有可枚举属性时,或者当你不知道一个集合是数组还是对象时(尽管这通常不是好的实践)。但是,它不适用于遍历数组,因为会返回索引而不是元素值,且会包含所有可枚举属性,包括通过原型链继承的属性。for...of:专门用于遍历可迭代对象的值。它是遍历数组、Map、Set等集合的推荐方式,因为它直接提供元素值,而不是索引或键。
3. 示例
for...in ****示例(遍历对象属性):
const obj = {a: 1, b: 2, c: 3};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
// 输出:a 1, b 2, c 3
注意:这里使用了 hasOwnProperty() 来避免遍历原型链上的属性。
for...of ****示例(遍历数组):
const arr = [1, 2, 3];
for (let value of arr) {
console.log(value);
}
// 输出:1, 2, 3
4. 兼容性
for...in:在 ECMAScript 5 及以后的版本中都是可用的。for...of:是 ECMAScript 6(ES2015)中引入的新语法,因此在一些旧版本的浏览器或环境中可能不可用。但是,现代浏览器和 Node.js 环境都支持它。
结论
在选择使用 for...in 还是 for...of 时,你应该根据你的具体需求和数据结构来决定。对于数组和类似数组的可迭代对象,推荐使用 for...of。对于遍历对象的属性,如果不需要考虑原型链上的属性,可以使用 Object.keys()、Object.values() 或 Object.entries() 结合 for...of,或者使用 for...in 但要小心处理原型链上的属性。