JavaScriptvariables声明外部或内部循环?

在AS3中我相信你应该初始化循环外的所有variables以提高性能。 这是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是parsing器的指令,而不是在运行时执行的命令。 如果一个特定的标识符在函数体(*)的任何地方声明了一次或多次var ,那么在该块中所有对该标识符的使用都将引用局部variables。 在循环内部,循环外部还是两者中声明value都是var都没有区别。

因此,你应该写出你发现最可读的。 我不同意克罗克福德把所有的variables放在函数的顶端总是最好的。 对于在一段代码中临时使用variables的情况,最好在该段中声明var ,这样该段就是独立的,并且可以被复制粘贴。 否则,在重构过程中将几行代码复制粘贴到一个新的函数中,而不需要单独提取和移动相关的var ,而且您已经得到了一个意外的全局variables。

尤其是:

 for (var i; i<100; i++) do something; for (var i; i<100; i++) do something else; 

Crockford会build议你删除第二个var (或者同时删除var s和var i;上面),并且jslint会为此而哀鸣。 但IMO更容易维护两个var ,将所有相关的代码保存在一起,而不是在函数的顶部添加一些额外的,容易被遗忘的代码。

就个人而言,我倾向于在独立的代码段中声明var作为variables的第一个赋值,而不pipe在同一个函数的某个其他部分是否存在另一个单独的用法。 对我来说,不得不声明var是一个不合需要的JS疣(最好是将variables默认为本地)。 我不认为这是我的责任,也可以在JavaScript中复制ANSI C的旧版本的限制。

(*:除嵌套函数体外)

在理论上,它不应该在JavaScript中有任何区别,因为语言没有块范围,而只有function范围。

我不确定性能的论点,但是道格拉斯·克罗克福德(Douglas Crockford)仍然build议var语句应该是函数体中的第一个语句。 引用JavaScript编程语言的代码约定 :

JavaScript不具有块范围,因此在块中定义variables可能会使具有其他C族语言经验的程序员感到困惑。 定义函数顶部的所有variables。

我想他有一个问题,就像你在下面的例子中看到的那样。 在函数顶部声明variables不应该使读者误以为variablesi是在for循环块的范围内:

 function myFunction() { var i; // the scope of the variables is very clear for (i = 0; i < 10; i++) { // ... } } 

ECMA-/Javascript语言hoists任何声明在函数顶部的variables。 那是因为这个语言确实function scope ,并没有像其他许多C语言那样的block scope
这也被称为lexical scope

如果你声明类似的东西

 var foo = function(){ for(var i = 0; i < 10; i++){ } }; 

这被hoisted起来:

 var foo = function(){ var i; for(i = 0; i < 10; i++){ } } 

所以它在性能上没有任何区别(但如果我在这里完全错误,请纠正我)。
不可以在函数顶部以外的地方声明一个variables的一个更好的参数是可读性 。 在for-loop声明一个variables可能会导致错误的假设,即只能在循环体内访问这个variables,这是完全错误的 。 事实上,你可以在当前范围内的任何地方访问这个variables。

明年,所有的浏览器都会有JS引擎对代码进行预编译,所以性能的差异(来自于一次又一次的parsing同一个代码块并执行赋值)应该变得微不足道。

另外,除非必须,否则绝不会优化性能。 保持variables接近你所需要的地方,第一次保持你的代码清洁。 不利的一面是,习惯于使用块范围的语言的人可能会感到困惑。

我只是在Chrome中做了一个简单的testing。 试试你的浏览器中的小提琴 ,看看结果

  var count = 100000000; var a = 0; console.log(new Date()); for (var i=0; i<count; i++) { a = a + 1 } console.log(new Date()); var j; for (j=0; j<count; j++) { a = a + 1; } console.log(new Date()); var j; for (j=0; j<count; j++) { var x; x = x + 1; } console.log(new Date()); 

结果是最后的testing需要8秒钟,而前2秒钟只需要2秒钟。 非常重复,不pipe顺序。

所以,这向我certificate,人们应该总是在循环之外宣布变数。 对我来说,奇怪的情况是i在for()语句中声明了i的第一个例子。 这个似乎和我预先声明索引的第二个testing一样快。

另外一个考虑因素,现在我们已经在ES2015中设置了letconst ,现在可以将variables的范围专门映射到循环块。 所以,除非你需要在循环之外使用相同的variables(或者如果每次迭代都依赖于前一次迭代中对该variables所做的操作),那么最好这样做:

 for (let i = 0; i < 100; i++) { let value = somearray[i]; //do something with `value` } 

JavaScript是由C或C ++编写的一种语言,我不太确定它是哪一种。 其目的之一是节省处理内存的风险。 即使在C或C ++中,当variables在循环中声明时,也不必担心是否会占用大量资源。 你为什么要在JavaScript中担心呢?

那么,这取决于你想要实现什么…如果value假设只是循环块内的一个临时variables,那么使用第二种forms会更清晰。 这也更加合乎逻辑和冗长。

这里的问题基本上是在循环内声明一个var。 只要想一想,如果你这样做会发生什么:

 var a = 30; var a = 50; var a = 60; 

你觉得这是对的吗? 不…因为你不想多次声明一个variables。 当你在一个循环中声明一个variables不是循环运行多次声明吗? 当你使用严格的模式时,很显然它会打你一巴掌。 人们不同意克罗克福德而不考虑原来的问题。

所以在上面声明variables总是很好的 – 1.为了可读性,2.养成良好的习惯。

对于在Linux操作系统上运行Chrome,Firefox和jsperftesting之后的性能,在循环中variables的声明和循环之外似乎存在性能差异。 这是一个小的差异,但这也是由迭代量和variables声明的数量。

因此,为了获得最佳性能,我将不得不build议在循环之外声明variables。 或者更好的是在行中声明你的variables。 看例子。

 // inline for (var ai = 0, al = 100000000, av; ai < al; ai++) { av = av + 1; } // outside var bv; var bl = 100000000; for (var bi = 0; bi < bl; bi++) { bv = bv + 1; } 

注意variables'al'和'av'是如何在for循环声明行中的。 这个内联声明为我提供了持续更好的性能。 即使在循环之外的variables的声明。 性能差异再次很小。

https://jsperf.com/outside-inline-for-loop-ase/1