在 JavaScript 的世界里,for 循环种类繁多,既有经典的传统款式,也有ES6的创新之作。让我们一起探索这四款循环:简单for、for-in、forEach,以及功能强大的for-of。每一种都独具特色,适用于不同的场景。
然而,for-in并非总是完美无缺,它在遍历数组时,包括了非索引属性,如在示例中添加的非数组属性:arr.name = "Hello world"; for(index in arr) { console.log("arr[" + index + "] = " + arr[index]);},需要注意的是,索引此时是字符串类型,而非数值。
for-in的局限性在于,它会遍历原型链,对于索引遍历,特别是稀疏数组,for-in只关注已存在的元素。为了优化,我们可以借助如arrayHasOwnIndex这样的辅助方法。
性能上,for-in并不如其他选项高效,特别是对于已知属性数量的情况。推荐使用for-of或props遍历,它们更为精准。
ES5的forEach,专注于数组元素,每个有效值都会被处理,但不会触及删除或未赋值的项。它的参数设计简洁:当前值、索引和数组本身。不过,forEach的遍历范围固定,对数组动态操作的影响有限。
当我们尝试遍历数组,如arr(已排除删除项):a 0, b 3, c 10,你会注意到index为Number类型,无需额外声明。ES5提供了诸如every、some、filter、map和reduce等其他工具,各有其独特之处。
for-of的出现,无疑提升了for循环的灵活性,它支持break、continue和return,适用于数组、类数组对象、字符串、Map和Set。它的简洁和响应性是其亮点,但不适用于普通对象属性的遍历,此时,for-in依旧是我们的首选。
最后,iter.next() 的输出揭示了for-of的内在机制:{ value: 'a', done: false }, { value: 'b', done: false }, { value: 'c', done: false }, { value: undefined, done: true }。这部分内容我们将深入解析,敬请期待后续的专题讨论。