在 AS3 中,我相信您应该初始化循环外的所有变量以提高性能。JavaScript 也是这种情况吗?哪个更好/更快/最佳实践?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
或者
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
在 AS3 中,我相信您应该初始化循环外的所有变量以提高性能。JavaScript 也是这种情况吗?哪个更好/更快/最佳实践?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
或者
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
有绝对没有区别意义还是性能,在JavaScript或ActionScript。
var
是解析器的指令,而不是在运行时执行的命令。如果var
在函数体 (*) 的任何地方已经声明了一次或多次特定标识符,则块中对该标识符的所有使用都将引用局部变量。是否value
声明var
在循环内、循环外或两者都没有区别。
因此,您应该编写任何您认为最易读的内容。我不同意 Crockford 的观点,即将所有变量放在函数顶部总是最好的。对于在一段代码中临时使用变量的情况,最好var
在该段中声明,这样该段是独立的,可以复制粘贴。否则,在重构期间将几行代码复制粘贴到新函数中,而无需单独挑选和移动关联的var
,您就会意外获得一个全局变量。
特别是:
for (var i; i<100; i++)
do something;
for (var i; i<100; i++)
do something else;
Crockford 会建议您删除第二个var
(或同时删除var
s 和 dovar i;
以上),并且 jslint 会为此向您发牢骚。但是 IMO 保留两个var
s更易于维护,将所有相关代码保存在一起,而不是在函数顶部添加额外的、容易忘记的代码。
就我个人而言,我倾向于var
在独立的代码部分中声明变量的第一次赋值,无论在同一函数的其他部分是否有另一个单独使用相同的变量名。对我来说,完全必须声明var
是一个不受欢迎的 JS 疣(最好让变量默认为本地);我不认为我有责任在 JavaScript 中复制 [旧版本] ANSI C 的限制。
(*: 嵌套函数体除外)
理论上它在 JavaScript 中不应该有任何区别,因为该语言没有块作用域,而只有函数作用域。
我不确定性能参数,但Douglas Crockford仍然建议这些var
语句应该是函数体中的第一条语句。引用JavaScript 编程语言的代码约定:
JavaScript 没有块作用域,因此在块中定义变量可能会使熟悉其他 C 系列语言的程序员感到困惑。在函数顶部定义所有变量。
我认为他说的有道理,你可以在下面的例子中看到。在函数顶部声明变量不应该让读者误以为变量i
保存在for
循环块的范围内:
function myFunction() {
var i; // the scope of the variables is very clear
for (i = 0; i < 10; i++) {
// ...
}
}
该ECMA-/Javascript
语言hoists
被宣布为一个函数的顶部任何地方的任何变量。这是因为这种语言也有function scope
和没有不具有block scope
像许多其他类似C语言。
这也称为lexical scope
.
如果你声明类似的东西
var foo = function(){
for(var i = 0; i < 10; i++){
}
};
这得到hoisted
:
var foo = function(){
var i;
for(i = 0; i < 10; i++){
}
}
所以它对性能没有任何影响(但如果我在这里完全错了,请纠正我)。不在函数顶部以外的其他地方声明变量的
一个更好的论据是可读性。在 a 中声明一个变量可能会导致错误的假设,即该变量只能在循环体内访问,这是完全错误的。事实上,您可以在当前范围内的任何地方访问该变量。for-loop
明年,所有浏览器都将拥有预编译代码的 JS 引擎,因此性能差异(来自一次又一次地解析相同的代码块加上执行赋值)应该可以忽略不计。
此外,除非必须,否则永远不要优化性能。将变量放在第一次需要它们的地方,可以保持代码整洁。不利的一面是,习惯于具有块作用域的语言的人可能会感到困惑。
另一个要考虑的,现在我们已经let
和const
在ES2015是,你现在可以作用域变量专门环形块。因此,除非您在循环外需要相同的变量(或者如果每次迭代都依赖于在前一次迭代中对该变量执行的操作),否则最好这样做:
for (let i = 0; i < 100; i++) {
let value = somearray[i];
//do something with `value`
}