我已经在几个地方读过,for-in循环比在数组上循环慢...虽然我知道在sizeof(类型)块中向前移动实际上是毫不费力的,而不是在场景后面发生的迭代一个物体的钥匙,我仍然很好奇,究竟是什么原因,它是如此缓慢......
是否必须使用反向哈希函数来获取密钥,而且该过程很慢?
答案 0 :(得分:4)
在任何特定引擎的情况下,对此的真正答案可能取决于该引擎的实现。 (差异的大小,如果有的话。)
但是,有不变量。例如,考虑:
var obj = {a: "alpha", b: "beta"};
var name;
for (name in obj) {
console.log(obj[name]);
}
var arr = ["alpha", "beta"];
var index;
for (index = 0; index < arr.length; ++index) {
console.log(arr[index]);
}
在obj
的情况下,引擎必须使用一种机制来跟踪您已经迭代过的属性以及哪些属性没有,以及过滤掉不可枚举的属性。例如,幕后有一些迭代器对象(以及定义规范的方式,可能是一个临时数组)。
在arr
的情况下,它没有;您正在以非常简单,有效的方式在代码中处理它。
每个循环的块的内容是相同的:对象的属性查找。 (在后一种情况下,理论上也有数字到字符串的转换。)
所以我希望唯一的非实现特定的答案是:额外的开销。
答案 1 :(得分:2)
for..each
循环使用iterators and generators。
Iterator是一个具有next()
方法的对象。 Generator是一个包含yield()
表达式的工厂函数。这两种结构都比整数索引变量更复杂。
在典型的for(var i = 0; i < arr.length; i++)
循环中,几乎在所有迭代中执行的两个命令是i++
和i < arr
。这可以说比进行函数调用(next()
或yield()
)要快得多。
此外,循环启动(var i = 0
)也比使用next()
方法创建迭代器对象或调用生成器来创建迭代器更快。但是,它在很大程度上取决于实现,Javascript引擎的创建者尽力加速这种常用的语言功能。
我想说差异是如此微不足道,以至于我可能想花时间优化代码的其他部分。当性能增益如此之小以至于增加复杂性时,语法的选择应该考虑代码可读性和可维护性而不是性能。话虽如此,使用对您和其他开发人员更有意义的语法,这些开发人员在您致富和着名后维护您的代码! ;)