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


76

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

window.something = "whatever";

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

something = "whatever";

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


2
这是不是真的与你的具体情况,但请记住,JavaScript不具备在浏览器中运行,所以窗口不被定义。
AndreiBârsan13年

Answers:


75

没有不同。它们都具有相同的效果(在浏览器中,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


4
顺便说一句,您可以删除window.foo,但不能删除用var定义的全局foo。
肯尼伯

8
它们是有区别的。window.foo = bar;在窗口对象上设置foo。foo = bar;搜索作用域链,直到找到为止foo,这可能最终成为全局对象,但并非总是如此。
大卫

@kennebec我相信这是特定于浏览器的。
雷诺斯2011年

@Raynos:能够删除的区别并不是特定于浏览器的。根据ECMAScript规范并假定window是全局对象,@ kennebec描述的行为是正确的。但是,旧版本的IE不符合要求。
蒂姆·唐

@TimDown它不应该是特定于浏览器的,但是它是。但是,我同意ES规范指出您可以删除属性。
雷诺斯2011年

10

他们俩都做同样的事情。
但是通过访问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视图中运行),则可能不是。


2

区别在于window.foo = bar;无法通过稍后进行的重构来拦截。使用foo = bar;表示如果以后var foo再将代码移动到已定义的闭包中,则不再将其设置在全局对象上。


0

再加一点:

如果你是指一个未声明的变量直接(不使用-窗口typeof运算),那么你会得到一个变量没有定义的错误

例子:

// 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
}

0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.