简体   繁体   English

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

[英]What's the difference between a global variable and a 'window.variable' in JavaScript?

I'm reading the Backbone.js documents and am seeing a lot of code that assigns attributes to the window object:我正在阅读Backbone.js文档,并且看到很多将属性分配给window object 的代码:

window.something = "whatever";

What's the difference between calling this code, and just assigning the variable and creating a global variable, like this:调用此代码与仅分配变量并创建全局变量有什么区别,如下所示:

something = "whatever";

I assume there is some kind of scope difference, and/or object ownership difference ( window being the owner vs. not), but I am interested in the detail between the two and why I would use window vs. not use it. I assume there is some kind of scope difference, and/or object ownership difference ( window being the owner vs. not), but I am interested in the detail between the two and why I would use window vs. not use it.

No difference.没有不同。 They both have the same effect (In the browser, where window is the global context 1 ).它们都具有相同的效果(在浏览器中, window是全局上下文1 )。

  • window.foo = "bar" sets the property foo on window . window.foo = "bar"window上设置属性foo
  • foo = "bar" indicates either a typo or intentionally global. foo = "bar"表示拼写错误或故意全局。

Since I have to double check whether it's a typo or not, I personally find it more readable to set window.foo directly.由于我必须仔细检查它是否是拼写错误,我个人认为直接设置window.foo更具可读性

Also, in ES5 strict mode, foo = "bar" is an illegal assignment because foo is not declared and will throw a Error .此外,在 ES5 严格模式下, foo = "bar"是非法赋值,因为foo没有声明并且会抛出Error

Edit:编辑:

As noted in the comments, foo = "bar" will look all the way up the scope chain for the variable foo and re-assign it with "bar" if it's found.如评论中所述, foo = "bar"将在 scope 链中一直查找变量foo并在找到时将其重新分配为"bar" If it's not found, it will create a new global variable.如果没有找到,它将创建一个新的全局变量。

Also with window.foo = "bar" you're just assigning a property to an object, which can be deleted using delete window.foo .同样使用window.foo = "bar"您只是将属性分配给 object,可以使用delete window.foo

In ES5 strict mode it is invalid to delete a variable.在 ES5 严格模式下, delete变量是无效的。


1 In other environments, such as node.js and Web Workers, there may be another name for the global object and window may not exist at all. 1在其他环境中,如 node.js 和 Web Worker 中,全局 object 和window可能不存在其他名称。 Node.js uses global and Web Workers use self . Node.js 使用global和 Web 工人使用self

They both kind of do the same thing.他们都做同样的事情。
But by accessing a window property, you know for sure that you're accessing a global variable no matter what scope you're in.但是通过访问window属性,您可以确定您正在访问一个全局变量,无论您在哪个 scope 中。
For example:例如:

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

In other words, If you want to work with globals, it's somewhat safer to access them via their container: window.variable换句话说,如果你想使用全局变量,通过它们的容器访问它们会更安全一些: window.variable

The key, as Raynos alluded to, is that it's set explicitly on the window object.正如 Raynos 所暗示的,关键是它在 window object 上明确设置。 In the browser, the global object is the same as the window object but in other environments (eg node.js, or perhaps running in a web view of some sort on a mobile device), it may not. In the browser, the global object is the same as the window object but in other environments (eg node.js, or perhaps running in a web view of some sort on a mobile device), it may not.

The difference is that window.foo = bar;不同的是window.foo = bar; cannot be intercepted by refactoring done later.无法通过稍后进行的重构来拦截。 Using foo = bar;使用foo = bar; means that if, at a later date, the code is moved into a closure where var foo has been defined, it will no longer set it on the global object.意味着如果以后代码被移动到定义了var foo的闭包中,它将不再在全局 object 上设置它。

Adding one more point:再补充一点:

If you refer an undeclared variable directly (without using - window or typeof ) then you will get a variable is not defined error .如果您直接引用未声明的变量(不使用-windowtypeof ),那么您将得到一个 variable is not defined错误

Examples:例子:

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

Unresolved references (aka undeclared variables) are actually not variables, they get added as a property to the global object.未解析的引用(又称未声明的变量)实际上不是变量,它们作为属性添加到全局 object。 [5c] [5c]

In strict mode ("use strict"), unresolved references throw a ReferenceError.在严格模式(“使用严格”)中,未解析的引用会引发 ReferenceError。 This is to avoid adding properties to the global object that were meant to be declared variables.这是为了避免向全局 object 添加要声明为变量的属性。 In this case if you do want to add a property to the global object you would use window.foo = "bar".在这种情况下,如果您确实想向全局 object 添加属性,您将使用 window.foo = "bar"。 [5a] [5a]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM