我相信在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];
}
Answers:
有绝对没有区别意义还是性能,在JavaScript或ActionScript。
var
是解析器的指令,而不是运行时执行的命令。如果某个特定标识符var
在函数体(*)中的任何位置一次或多次声明,则该标识符在块中的所有使用将引用局部变量。value
声明是var
在循环内,在循环外还是在两者上都没有区别。
因此,您应该写出最容易阅读的内容。我不同意Crockford的观点,将所有var放在函数顶部始终是最好的选择。对于在代码部分中临时使用变量的情况,最好var
在该部分中进行声明,因此该部分可以独立存在并可以复制粘贴。否则,在重构过程中将几行代码复制粘贴到新函数中,而无需分别挑选并移动关联的var
,这会使您自己成为意外的全局对象。
特别是:
for (var i; i<100; i++)
do something;
for (var i; i<100; i++)
do something else;
Crockford将建议您删除第二个var
(或同时删除var
s和do var i;
),而jslint会为此向您请教。但是IMO将两个都var
保留在一起,将所有相关代码保持在一起,而不是在函数顶部保留一些容易忘记的额外代码,是更可维护的。
我个人倾向于将var
变量声明为代码的独立部分中的第一个赋值,无论是否在同一函数的其他部分中单独使用了同一变量名。对我来说,var
根本不需要声明是一个不受欢迎的JS wart(最好将变量默认设置为local)。我不认为在JavaScript中复制ANSI C的旧版本的限制不是我的责任。
(*:嵌套函数体中除外)
var
仅在函数顶部使用仅要求意外创建全局变量。而且,在一个地方声明所有不相关变量的数量在语义上是没有意义的,尤其是当其中一些变量最终可能永远都不会被使用时。
从理论上讲,它在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
也会在运行时将其增大。那就是所谓的“吊装”。因此,应该没有任何区别。
let
影响此答案?
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
可能导致错误的假设,即只能在循环体内访问此变量,这是完全错误的。实际上,您可以在当前范围内的任何位置访问该变量。
let
影响此答案?
明年,所有浏览器都将具有可预编译代码的JS引擎,因此性能差异(来自一次又一次地解析同一代码块再加上执行分配)的性能差异应该可以忽略不计。
另外,除非必须这样做,否则请不要针对性能进行优化。将变量保持在第一次需要它们的地方,以保持代码干净。不利的一面是,习惯于使用块作用域语言的人可能会感到困惑。
我只是在Chrome中做了一个简单的测试。在浏览器中尝试小提琴并查看结果
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());
结果是最后一个测试大约需要8秒钟,而前2个测试仅需要2秒钟。非常可重复,无论顺序如何。
因此,这向我证明了,应该始终在循环外部声明var。对我来说,奇怪的案例是我i
在for()语句中声明的第一个案例。这个速度似乎和我预先声明索引的第二次测试一样快。
var
声明为全局变量,无论如何都要全球化。
JavaScript是由C或C ++底层编写的一种语言,我不太确定它是哪一种。其目的之一是节省处理内部存储器的需求。即使在C或C ++中,也不必担心在循环内声明变量时它是否会消耗大量资源。为什么要在JavaScript中担心它?
好吧,这取决于您要实现的目标...如果value
假设只是循环块中的一个临时变量,那么使用第二种形式会更加清晰。这也更加合逻辑和冗长。
如果在for循环内部或外部声明变量,则没有区别。下面是要测试的示例代码。
function a() {
console.log('Function a() starts');
console.log(new Date());
var j;
for (j=0; j<100000000; j++) {
var x;
x = x + 1;
}
console.log(new Date());
console.log('Function a() Ends');
}
a()
function b() {
console.log('Function B() starts');
console.log(new Date());
var a;
var j;
for (j=0; j<100000000; j++) {
a = a + 1;
}
console.log(new Date());
console.log('Function B() Ends');
}
b()
结果显示在我的情况下
Function a() starts
VM121:3 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:9 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:10 Function a() Ends
VM121:14 Function B() starts
VM121:15 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:21 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:22 Function B() Ends
谢谢-MyFavs.in
let
,而不是var
和a()
往往是有点慢(如120 VS 115毫秒=〜6%= IMO微不足道)
这里的问题基本上是在循环内声明var。试想一下,如果执行此操作会发生什么:
var a = 30;
var a = 50;
var a = 60;
你认为这是对的吗?不...因为您不想多次声明变量。当您在循环内声明变量时,是不是声明了循环运行了多少次?显然,当您处于“使用严格”模式时,它会打您一巴掌。人们不同意克罗克福德而未考虑原始问题。
因此,始终最好在顶部声明变量-1.为了便于阅读,2.养成良好的习惯。
关于在Linux OS上的Chrome,Firefox和jsperf上运行测试后的性能,在循环中和循环外的变量声明之间确实存在性能差异。这是一个很小的差异,但是迭代次数和变量声明的数量也使情况更加复杂。
因此,为了获得最佳性能,我将不得不建议在循环外声明变量。或者更好地声明您的变量。参见示例。
// 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;
}
注意变量“ al”和“ av”在for循环声明行中的情况。此内联声明为我提供了始终更好的性能。甚至在循环外声明变量。同样,性能差异确实很小。