在以下代码中:
for (var i = 0; i < object.length; i++){
....
}
每次迭代都会对操作object.length
进行评估吗?
最有意义的是语言将对此进行一次评估并保存结果。但是,我正在阅读一些代码,其中某人在循环开始之前评估了操作并将其存储在最终条件中使用的变量中。
不同的语言处理不同吗? Javascript的任何特定信息?
答案 0 :(得分:8)
这显然取决于语言。对于JavaScript,规范(ECMAScript§12.6.3)要求每次都要对它进行评估。作为优化,特定的JavaScript运行时可以跳过一个或多个长度调用,如果它可以证明结果不会改变。
答案 1 :(得分:3)
完全取决于语言和(可能)循环中的内容。编译器/解释器可能或可能无法确定“长度”属性不会被循环中的某些内容更改。
在Javascript中,可以肯定的是,它会被重新评估。像这样的简单属性引用可能并不坏,但像函数调用之类的东西可能是性能问题。 编辑为了澄清,通过“函数调用”,我的意思是任何形式的代码,以任何方式计算循环终止条件,使你在每次迭代时都感觉不好。
因此(原谅我的jQuery),
for (var i = 0; i < $('.foo').length; ++i) { /* ... */ }
将涉及每次迭代遍历整个DOM。
答案 2 :(得分:2)
必须在循环的每次迭代中重新评估条件,因为理论上该值可能在循环体内发生了变化。
答案 3 :(得分:2)
智能编译器可以自动针对这种情况进行优化,但是在JavaScript中执行静态分析以确定不会在循环内部发生变化是非常困难的。出于这个原因,您可以说在大多数情况下{/ 1}}确实会在每次迭代中重新评估。
另一方面,程序员通常更容易推断长度肯定不会改变,如果你真的(我的意思是,真的)担心性能,你可以在循环开始之前预先计算并存储长度。
答案 4 :(得分:2)
如果订单对您无关紧要,请向后迭代。在这种情况下,您不需要保持长度的杂乱临时变量。循环的 start 条件只被评估一次(显然,一旦循环已经开始,它将毫无意义地重新评估它!)。使用早期响应中的示例:
for (var i = $('.foo').length - 1; i >= 0; i--) { /* ... */ }
我知道我在问这个问题后很长时间没有回答这个问题,但是在搜索结果中它仍然显示相关查询,并且现有的答案似乎都没有提出这种替代方法。
答案 5 :(得分:1)
在某些语言中,这取决于您在构建时配置的优化级别。我相信C ++,例如,将字段标记为易变将强制重新评估。看看这些链接:
答案 6 :(得分:0)
在Javascript中,它每次都会得到评估。您可以通过在循环的第一部分设置“max”变量来绕过它:
for (var i=0, imax=object.length; i<imax; i++) {
// statements
}
答案 7 :(得分:0)
是的,它会在每次迭代时计算出来。
为什么不试试呢?
var loop = 5;
for (var i = 0; i< loop; i++)
{
alert(i + ' of ' + loop);
loop--;
}