遍历方法2

遍历方法2

forin

在 JavaScript 中,for...in 循环主要用于遍历对象的可枚举属性,而 数组的索引本质上是对象的属性名(字符串类型)。以下是具体用法和注意事项:

1. for...in 获取索引的原理

当遍历数组时,for...in 的循环变量会依次返回数组的 索引字符串(如 "0", "1"),而非数值类型的索引。需要手动转换为数字:

1
2
3
4
5
6
7
8
9
const arr = ['a', 'b', 'c'];
for (const indexStr in arr) {
const index = parseInt(indexStr, 10); // 转为数字类型
console.log(index, arr[index]);
}
// 输出:
// 0 a
// 1 b
// 2 c

2. 问题与风险

虽然可以用 for...in 遍历数组,但不推荐,因为:

  • 可能遍历到非数字属性:如果数组被扩展了自定义属性,会被一起遍历。
  • 原型链污染:如果原型链上有可枚举属性(如通过 Array.prototype.foo = ... 添加),也会被遍历。
  • 顺序不保证:虽然现代浏览器按顺序遍历数组索引,但规范不强制保证顺序。
    示例问题:
1
2
3
4
5
const arr = ['a', 'b'];
arr.foo = 'bar'; // 添加自定义属性
for (const indexStr in arr) {
console.log(indexStr); // 输出: "0", "1", "foo"
}

3. 正确替代方案

(1) 使用 for 循环

直接通过数字索引遍历:

1
2
3
for (let i = 0; i < arr.length; i++) {
console.log(i, arr[i]);
}

(2) 使用 forEach

直接获取元素和索引:

1
2
3
arr.forEach((item, index) => {
console.log(index, item);
});

(3) 使用 for...of + entries()

同时获取索引和值:

1
2
3
for (const [index, value] of arr.entries()) {
console.log(index, value);
}

4. for...in 的正确用途

仅推荐用于遍历普通对象的属性

1
2
3
4
5
6
const obj = { name: 'Alice', age: 30 };
for (const key in obj) {
if (obj.hasOwnProperty(key)) { // 过滤原型链属性
console.log(key, obj[key]);
}
}

总结

  • 如果目标是遍历数组索引,不要使用 for...in,优先选择 forforEachfor...of
  • for...in 应严格用于遍历对象的属性,并配合 hasOwnProperty 过滤原型链。