【问题标题】:What's the difference between a global var and a window.variable in javascript?javascript中的全局变量和window.variable有什么区别?
【发布时间】:2011-09-15 00:11:31
【问题描述】:

我正在阅读backbone.js 文档并看到很多将属性分配给窗口对象的代码:

window.something = "whatever";

调用此代码与仅分配变量并创建全局变量有什么区别,如下所示:

something = "whatever";

我假设存在某种不同的范围和/或对象所有权差异(窗口是所有者还是非所有者),但我对两者之间的细节以及为什么我会使用窗口而不是使用它感兴趣。

【问题讨论】:

  • 这与您的特定情况并没有真正的关系,但请记住,Javascript 没有 具有 可以在浏览器中运行,因此 window 没有 具有 被定义。

标签: javascript attributes scope


【解决方案1】:

未解析的引用(也称为未声明的变量)实际上不是变量,它们作为属性添加到全局对象中。 [5c]

在严格模式(“使用严格”)下,未解析的引用会引发 ReferenceError。这是为了避免向全局对象添加要声明为变量的属性。在这种情况下,如果您确实想向全局对象添加属性,您可以使用 window.foo = "bar"。 [5a]

【讨论】:

    【解决方案2】:

    再加一点:

    如果你直接引用一个未声明的变量(不使用-windowtypeof)那么你会得到一个未定义的变量错误

    例子:

    // var unDecVariable
    
    if (unDecVariable != null) // Error: unDecVariable is not defined
    {
        // do something
    }
    
    if (window.unDecVariable != null) // No Error
    {
        // do something
    }
    
    if (typeof unDecVariable != 'undefined' && unDecVariable != null) // Alternative way
    {
        // do something
    }
    

    【讨论】:

      【解决方案3】:

      没有区别。它们都具有相同的效果(在浏览器中,window 是全局上下文1)。

      • window.foo = "bar"window 上设置属性foo
      • foo = "bar" 表示拼写错误或故意全局化。

      由于我必须仔细检查是否是拼写错误,我个人认为直接设置window.foo可读

      另外,在 ES5 严格模式下,foo = "bar" 是非法赋值,因为 foo 没有被声明并且会抛出 Error

      编辑:

      如 cmets 中所述,foo = "bar" 将一直查找变量 foo 的作用域链,如果找到,则使用 "bar" 重新分配它。如果没有找到,它会创建一个新的全局变量。

      同样使用window.foo = "bar",您只是将属性分配给对象,可以使用delete window.foo 删除。

      在 ES5 严格模式下,对于 delete 一个变量是无效


      1 在其他环境中,例如 node.js 和 Web Workers,全局对象可能有另一个名称,window 可能根本不存在。 Node.js 使用global,Web Workers 使用self

      【讨论】:

      • 顺便说一句,您可以删除 window.foo 但不能删除用 var 定义的全局 foo。
      • 有区别。 window.foo = bar; 在窗口对象上设置 foo。 foo = bar; 向上搜索作用域链,直到找到 foo,这可能最终成为全局对象,但并非总是如此。
      • @kennebec 我相信这是特定于浏览器的。
      • @Raynos:能够删除的区别并不是特定于浏览器的。根据 ECMAScript 规范并假设 window 是全局对象,@kennebec 描述的行为是正确的。但是,旧版本的 IE 不符合要求。
      • @TimDown 它不应该是特定于浏览器的,但它是。不过我同意 ES 规范说你可以删除属性。
      【解决方案4】:

      他们都做同样的事情。
      但是通过访问 window 属性,您可以确定您正在访问一个全局变量,无论您在什么范围内。
      例如:

      globalVar = "smth";
      function(){
          var globalVar = 2;
          alert(globalVar);// points to the current scope globalVar
          alert(window.globalVar);// points to the original globalVar
      }
      

      换句话说,如果你想使用全局变量,通过容器访问它们会更安全一些:window.variable

      【讨论】:

        【解决方案5】:

        正如 Raynos 所暗示的,关键在于它是在窗口对象上显式设置的。在浏览器中,全局对象与 window 对象相同,但在其他环境中(例如 node.js,或者可能在移动设备上以某种 Web 视图运行),它可能不会。

        【讨论】:

          【解决方案6】:

          不同之处在于window.foo = bar; 不能被稍后进行的重构拦截。 使用foo = bar; 意味着如果以后将代码移动到定义了var foo 的闭包中,它将不再在全局对象上设置它。

          【讨论】:

            猜你喜欢
            • 2018-04-23
            • 2016-01-17
            • 2011-01-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-17
            • 1970-01-01
            相关资源
            最近更新 更多