You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中for...in与for...of循环差异及混用生效原因探究

JavaScript中for...in与for...of的底层差异及混用问题解析

核心底层逻辑差异

  • for...in循环:本质是遍历对象的可枚举属性名。数组在JS里属于特殊对象,它的可枚举属性就是字符串类型的索引(比如"0"、"1"),遍历过程中拿到的是这些字符串形式的索引值。
  • for...of循环:遍历的是可迭代对象的迭代器返回值。数组的内置迭代器会直接返回每个元素的实际值,所以能直接拿到数组里的1、2、3这类元素。

你的两种场景分析

1. 输出奇数时“生效”的巧合

你写的代码:

let numbers = [1,2,3,4,5,6,7,8,9,10]
function displayOddNumbers() {
    for (num in numbers) {
        num % 2 != 0 ? console.log(num) : console.log();
    };
};

这里num是数组的索引(字符串类型,比如"1"),在执行num % 2时,JS会自动把字符串转成数字。你输出的是奇数索引(1、3、5、7、9),而这些索引的数值刚好和数组里的奇数元素(1、3、5、7、9)完全一致,所以你误以为代码正确——但本质是输出了索引,只是数值巧合匹配了目标元素。如果数组元素不是从1开始的连续整数,这个代码会直接出错。

2. 输出偶数时失效与修正的原因

最初的失效代码:

function displayEvenNumbers() {
    for (num in numbers) {
        num % 2 == 0 ? console.log(num) : console.log();
    };
};

你想输出偶数元素,但这里输出的是偶数索引(0、2、4、6、8),这些索引对应的数组元素是1、3、5、7、9(奇数),完全不是你要的结果,所以看起来“失效”。

修改后的代码:

function displayEvenNumbers() {
    for (num in numbers) {
        num % 2 != 0 ? console.log(numbers[num]) : console.log();
    };
};

这里你通过numbers[num]取到了奇数索引对应的数组元素(索引1→2、索引3→4...),这些元素刚好是你要的偶数,所以代码“生效”。但这个逻辑是绕了弯路的:你通过判断索引的奇偶性,反向拿到了目标元素,本质还是利用了数组索引和元素值的对应关系,不是正确的遍历方式。

总结

遍历数组优先用for...of、普通for循环或forEach,for...in是为遍历普通对象的属性设计的,用来遍历数组会因为以下问题出错:

  • 拿到的是字符串类型的索引,容易在隐式转换中产生意外
  • 可能遍历到数组原型上的自定义可枚举属性
  • 遍历顺序不保证严格按数组索引顺序

内容的提问来源于stack exchange,提问作者user53

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:23:17