当前位置:  开发笔记 > 编程语言 > 正文

JavaScript变量声明在循环外部或内部?

如何解决《JavaScript变量声明在循环外部或内部?》经验,为你挑选了4个好方法。

在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];
}

bobince.. 272

绝对没有区别意义还是性能,在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(或者删除vars并在var i;上面执行),jslint会为此向你发牢骚.但IMO更容易维护两者var,将所有相关代码保持在一起,而不是在函数顶部有一个额外的,容易被遗忘的代码.

就个人而言,我倾向于var在一个独立的代码段中声明一个变量的第一个赋值,无论是否在同一个函数的某个其他部分中另一个单独使用相同的变量名.对我来说,必须要声明var是一个不受欢迎的JS疣(将变量默认为local更好); 我不认为我有责任在JavaScript中复制[旧版本] ANSI C的限制.

(*:除嵌套函数体外)



1> bobince..:

绝对没有区别意义还是性能,在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(或者删除vars并在var i;上面执行),jslint会为此向你发牢骚.但IMO更容易维护两者var,将所有相关代码保持在一起,而不是在函数顶部有一个额外的,容易被遗忘的代码.

就个人而言,我倾向于var在一个独立的代码段中声明一个变量的第一个赋值,无论是否在同一个函数的某个其他部分中另一个单独使用相同的变量名.对我来说,必须要声明var是一个不受欢迎的JS疣(将变量默认为local更好); 我不认为我有责任在JavaScript中复制[旧版本] ANSI C的限制.

(*:除嵌套函数体外)


+1 Crockford对于这个(和其他人,但我离题)是错误的.要求`var`仅用于函数的顶部只是要求意外的全局变量创建.并且在一个地方声明大量不相关的变量在语义上毫无意义,特别是当这些变量中的一些最终可能永远不被使用时.
循环索引不是特殊情况,它们的处理和提升方式与正常分配完全相同.
+1我不同意Crockford的推理(在Daniel的回答中引用),因为JavaScript开发人员不应该编写代码以便其他"C系列"程序员能够理解它.我经常使用*var*inside*if*blocks和loops,因为它对我来说更有意义.
我仍然无法决定我是否与克罗克福德在一起.在块内声明变量感觉有点像使用条件函数语句(这是顽皮的)......但是,我同意你的观点:) #confused
-1 OP在循环开始之前询问是否应该声明循环体中的变量.循环的索引值显然是一个特殊情况(并且被提升)并且根本不帮助OP.
@MooGoo:他会告诉你使用[jsLint](http://www.jslint.com/)来避免你提到的问题:)

2> Daniel Vassa..:

理论上它不应该在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++) {
    // ...
  }
}


+1告诉OP有关JS范围的真相.我想知道是否要回答说不然的答案!
@Kieranmaine:AFAIK即使你在循环中声明变量,`ecma-/javascript`也会在运行时将这些变量搞砸.这被称为"吊装".所以应该没有任何区别.

3> jAndy..:

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


ES6的'let`如何影响这个答案?

4> Aaron Digull..:

Next year, all browsers will have JS engines that precompile the code so the performance difference (which comes from parsing the same block of code again and again plus executing the assignment) should become negligible.

Also, never optimize for performance unless you have to. Keeping variables close to the place where you need them the first time keeps your code clean. On the negative side, people who are used to languages with block scopes might be confused.

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有