我应该使用window.variable还是var?

时间:2011-08-01 20:39:58

标签: javascript global-variables

我们有很多设置JS代码,用于定义将在许多其他JS文件中使用的面板,按钮等。

通常,我们会这样做:

grid.js

var myGrid = .....

combos.js

var myCombo = .....

然后,在我们的应用程序代码中,我们:

的application.js

function blah() {
    myGrid.someMethod()
}

someother.js

function foo() {
    myCombo.someMethod();
    myGrid.someMethod();
}

因此,我们应该使用var myGrid还是更好地使用window.myGrid

有什么区别?

7 个答案:

答案 0 :(得分:56)

功能上可能存在的重要差异是window.myGrid可能是delete d,而var myGrid则不能。

var test1 = 'value';
window.test2 = 'value';


console.log( delete window.test1 ); // false ( was not deleted )
console.log( delete window.test2 ); // true  ( was deleted )


console.log( test1 );  // 'value'         ( still accessible )
console.log( test2 );  // ReferenceError  ( no longer exists )

答案 1 :(得分:40)

我建议创建命名空间变量var App = {};

App.myGrid = ...

这样就可以限制全局命名空间的污染。

编辑:关于变量发布的数量 - 我想到了两种可能的解决方案:

  1. 您可以按类型(网格,按钮等)或关系(ClientInfoSection,AddressSection等)进一步命名它们
  2. 您将方法封装在使用您拥有的组件进行实例化的对象中
  3. 前:你有

    function foo() {
        myCombo.someMethod();
        myGrid.someMethod();
    }
    

    变为:

    var Foo = function(combo, grid) {
        var myCombo = combo;//will be a private property
        this.myGrid = grid;//will be a public property
        this.foo = function() {//public method
            myCombo.someMethod();
            myGrid.someMethod();
        }
    }
    App.myFoo = new Foo(someCombo, someGrid);
    App.myFoo.foo();
    

    这样你就可以限制小对象的数量,只暴露你需要的东西(即foo函数)

    PS:如果你需要公开内部组件,那么在构造函数

    中添加它们

答案 2 :(得分:10)

window.variable的一个很好的用途是你可以检查它而不会出现javascript错误。例如,如果您有:

if (myVar) {
    //do work
}

并且myVar未在页面的任何位置定义,您将收到javascript错误。但是:

if (window.myVar) {
    //do work
}

没有错误,并且按照人们的预期工作。

var myVar = 'test'window.myVar = 'test'大致相同。

除此之外,正如其他人所说,你应该从一个全局对象下降,以避免污染全局命名空间。

答案 3 :(得分:8)

在全球范围内,这两者实际上是功能相同的。在函数范围中,当需要闭包行为时,var当然更可取。

我只会一直使用var:首先,它与闭包中通常首选的行为一致(因此,如果您稍后决定将代码移动到闭包中更容易),其次,我只是觉得我正在创建一个变量而不是附加窗口的属性。但现在它主要是风格。

答案 4 :(得分:6)

问题的一般答案是使用var

更具体地说,始终将您的代码放在Immediately Invoked Function Expression (IIFE)

(function(){
  var foo,
      bar;
  ...code...
})();

这使像foobar这样的变量不会污染全局命名空间。然后,当你明确想要一个变量在全局对象上时(通常是window),你可以写:

window.foo = foo;

JavaScript具有功能范围,充分利用它真的很好。你不希望你的应用程序破解只是因为其他程序员做了一些愚蠢的事情,就像覆盖你的计时器句柄一样。

答案 5 :(得分:3)

除了其他答案之外,值得注意的是,如果在声明变量时未在函数内部使用var,则泄漏到自动范围内,使其成为属性window对象(或全局范围)。

答案 6 :(得分:1)

要扩展Liviu所说的内容,请使用:

App = (function() {
    var exports = {};
    /* code goes here, attach to exports to create Public API */
    return exports; 
})();

通过这样做,您可以隐藏一些特定于实现的代码,您可能不希望使用var内部暴露这些代码。但是,您可以访问附加到exports对象的任何内容。