javascript 中的全局变量和 window.variable 有什么区别?

IT技术 javascript attributes scope
2021-01-18 08:10:52

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

window.something = "whatever";

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

something = "whatever";

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

6个回答

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

  • window.foo = "bar"设置该属性foowindow
  • foo = "bar"表示打字错误或故意全局。

由于我必须仔细检查它是否是一个错字,我个人觉得直接设置它更具可读性window.foo

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

编辑:

如评论中所述,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 = bar;在 window 对象上设置 foo。foo = bar;向上搜索作用域链,直到找到foo,这可能最终成为全局对象,但并非总是如此。
2021-03-15 08:10:52
顺便说一句,您可以删除 window.foo 但不能删除使用 var 定义的全局 foo。
2021-03-16 08:10:52
@Raynos:能够删除的区别并不是特定于浏览器的。根据 ECMAScript 规范并假设window是全局对象,@kennebec 描述的行为是正确的。但是,旧版本的 IE 不符合要求。
2021-03-24 08:10:52
@TimDown 它不应该是特定于浏览器的,但它是。但是我同意 ES 规范说您可以删除属性。
2021-03-28 08:10:52
@kennebec 我相信这是特定于浏览器的。
2021-03-31 08:10:52

他们都做同样的事情。
但是通过访问一个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

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

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

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

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