3

除了可读性......在效率和/或功能方面,我不清楚将声明放置在外部(我的实践)或循环内部(在其他 SO 帖子中看到)之间的区别。或者就此而言,为什么要代码声明?这里有一些退化的例子......下面有更多评论。

A1:

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

A2:

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

B1:

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

B2:

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

C1:

var x;
var y;

C2:

var x, y;

除了可读性...我怀疑 B1 和 B2 之间以及 C1 和 C2 之间没有区别,但对 A1 和 A2 之间的效率或功能差异持怀疑态度。另外,除了在函数中使用声明来消除(?)与同名全局变量的可能冲突之外,我不确定声明有什么优势。

编辑:添加了几个分号

编辑:第一句清晰度,将功能更改为功能

编辑:在下面添加一些代码以帮助我在下面发表评论编辑:评论

<!doctype html>
<html>
<head>
<script type='text/javascript'>
var w = (function(){  // wrapper
    alert('init');
    function p(){ // private
        alert('p');
        w.b(); //needs prefix
    }
    return{
        a: function(){ // public
            alert('a'); 
            p();
            w.b(); // needs prefix 
        },
        b: function(){ // public
            alert('b'); 
        }
    };
})(); // execute immediately
</script>
<script type="text/javascript">window.onload=w.a;</script>
</head>
<body>
sequence of alerts will be 'init' 'a' 'p' 'b'
</body>
</html>
4

4 回答 4

3

变量声明被提升到函数的顶部。它不会有任何区别,除非您当然是在谈论在新的函数范围内声明一个变量。


编辑:起初没有注意到,你的第一个例子没有ivar. 这不是好的做法。


编辑:

通常最好避免创建全局变量,以避免与可能设置全局变量的其他脚本发生冲突。

每当你使用一个变量而不用 声明它时var,它就会变成全局变量。

在 JavaScript 中创建新变量范围的唯一方法是在函数体中。函数可以相互嵌套,创建一个范围链,从最里面的函数开始,到全局范围结束。

因此,通常将所有代码放在一个立即调用的函数中。这样,您创建的任何变量var都不会最终成为全局变量。

(function() {   // <-- create a function

    // place your code in here

      // use "var" when declaring variables so they don't become global
    var name = "patrick dw";

    alert( name );

})(); // <-- invoke the function immediately so your code runs

在前面的例子中,name变量对于立即调用的函数是局部的,不会污染全局范围。

因为遍历变量范围需要一些资源,所以人们通常在调用该函数时传入一些参数,例如window.

(function( window, undefined ) {

      // now the window object is referenced locally. Better for performance.

    var name = "patrick dw";

    alert( name );

})( window ); // <-- invoke the function passing in the global "window" object

现在该window对象在您的函数内部被本地引用,因此如果您访问 的某个属性window,它就不必一直跟随您的函数外部的范围链。

我还在函数中包含了一个额外的undefined参数,但没有将参数传递给它。这是为了帮助避免一些不良编码实践带来的奇怪问题。但这是另一个问题。

现在采用相同的函数,如果我们不使用var声明name变量,它会自动变成全局变量。我将更新示例,并添加另一个函数范围来说明。

(function( window, undefined ) {

          // create a function 
    function some_func() {

        name = "patrick dw";  // didn't use "var" when declaring!!
        alert( name );
    }

    some_func();  // call our function

    alert( window.name ); // but "name" is also accessible from the global window

})( window );

alert( name ); // outside those functions, we're global, and again we can see that
               //   the "name" variable is accessible

如您所见,我们从未声明var name,因此即使它嵌套了两个函数,它也成为了一个自动全局变量。

这是许多错误的根源,也是您需要格外小心使用var.


最后,我要指出的是,当您在"strict mode";. 目前实现的浏览器并不多strict mode,但是在一个经常测试你的代码的时候会很有帮助。

这是 ECMAScript 5 的兼容性表。严格模式在底部。您会看到 Firefox 4 支持它。

这是一个例子:

(function( window, undefined ) {

    "strict mode"; // <-- use the strict mode directive

    name = "patrick dw";  // In Firefox 4, you should get a ReferenceError in the console
                          //   because "name" was never declared with "var"
})( window );
于 2011-05-18T20:14:50.650 回答
1

这一切都只是语法差异。我认为即使在 B 两个声明都在同一范围内。

仅在没有 var 的情况下声明 i 将导致它在全局范围内定义。

这主要是关于哪种选项最适合情况,同时仍应尽可能保持一致。

如果您已经有一个全局变量 x,我认为这不会阻止碰撞。

于 2011-05-18T20:23:34.300 回答
0

A1 或 A2 之间也没有功能或效率差异。尝试这个:

var arr=[];
for(var i=0; i<10; ++i) {
  var x=i;
  arr.push( function() {alert(x);} );
}
for(var i=0; i<10; ++i) {
  arr[i]();
}

您会看到所有函数显示的值都是相同的,因为它与所有函数使用的 x 相同。不是每次都创建新变量。

于 2011-05-18T20:18:59.843 回答
0

javascript 变量的作用域在 using 时与整个函数共享var,因此当 A1 和 A2 都在一个函数中时,它们之间不会有任何区别。

但是,您可以使用let关键字并将变量范围限制为块,例如:

for(let x = 0; x < 10; x++){}

这会将x变量限制为仅在 for{} 块内具有范围。

于 2011-05-18T20:16:08.937 回答