[Effective JavaScript 笔记]第49条:数组迭代要优先使用for循环而不是for...in循环

示例

下面代码中mean的输出值是多少?

var scores=[98,74,85,77,93,100,89];
var total=0;
for(var score in scores){
    total+=score;
}
var mean=total/scores.length;
mean;//? 17636.571428571428

用计算器手动算了一下,答案应该是88。说明这段代码的真正结果应该是88,但为什么实际结果不正确呢。这和for...in循环会枚举所有key,包括原型中的。也就是说上面的代码实际应该是(0+1+2+...+6)/7=21,但也不对。这里的key即使是数组的索引,对象属性也始终是字符串。因些,“+=”操作符将执行字符串的连接操作。结果就是total的值是"00123456"。mean最终结果是17636.571428571428。无法理解的一个结果。

使用传统的for循环

var scores=[98,74,85,77,93,100,89];
var total=0;
for(var i=0,n=scores.length;i < n;i++){
    total+=scores[i];
}
var mean=total/scores.length;
mean;//88 

该方法确保你需要整数索引和数组元素时就能获取到它们,并且绝不会混淆它们或引发字符串的强制转换。此外,它还可以确保正确的迭代数组,并且不会意外地包括存储在数组对象或其原型链中的非整数属性。

注意点

上面循环中对于变量n的使用,这可以在循环的时候,不用每次都获取一次数组的长度。
给阅读该代码的程序员传递一个信息:循环的终止条件是简单且确定的。

提示

    • 迭代数组的索引属性应当总是使用for循环而不是for...in循环

    • 考虑在循环之前将数组的长度存储在一个局部变量中以避免重新计算数组长度