window.x和x之间有什么区别?

时间:2013-05-07 02:05:20

标签: javascript

让我们说,“x”是一个从未定义的变量,所以它应该是未定义的。在以下场景中:
1)

if(x){//do something}
//ReferenceError: x is not defined

2)

if(window.x){//do something}
//worked as expected

据我所知,在这里的浏览器环境中,x应该与window.x相同,是否有人可以帮助指出这里不同行为的原因?

2 个答案:

答案 0 :(得分:4)

x只有window.x才会被声明(在全局范围内,自然而然)。这可以通过全局范围中的显式var语句或任何范围内没有var的简单赋值(被认为是隐式全局声明)来完成:

var a; // declares global a
function foo() {
    b = 10; // declares (implict) global b
}

ab在网络浏览器中也可以window.awindow.b使用。

这也会在浏览器上创建一个全局变量:

window.c = 20; // can be accessed as just c

现在,尝试访问不存在的变量会抛出 ReferenceError ,而尝试访问不存在的对象属性时,只返回undefined。

有趣的事实:globals created with var can't be removed with the delete operator,而隐式全局变量和作为全局对象属性创建的全局变量可以。

答案 1 :(得分:2)

JavaScript(作为核心语言)不提供任何方式来访问包含所有全局变量的对象( "Global Environment" ),但它仍然存在。在Web浏览器中,全局环境有一个名为window(以及self,也许top)的变量,它引用了全局上下文。

如果您愿意,可以输入window.window.self.top.window.top.window.x。 :)

因此,在没有定义本地var xvar y的上下文中,此代码

x = 42;
window.y = 17;

...将在全局上下文中分配两个变量,以及此代码:

console.log(window.x);
console.log(y);

...将从全局上下文中读取值。

JavaScript(如Lua和Ruby)允许您设置全局变量的值,而无需将变量预定义为全局变量。 (但请注意,this is disallowed in ECMAScript5 strict mode。)

但是,JavaScript(与Lua和Ruby不同)显式不允许您访问未设置的全局变量(请参阅ECMAScript 5 specification section 8.7.1,第3步。)这样做是为了保护您在发错时不小心读取全局变量。在Lua你可以写:

myLongNamedGlobalVariable = 42   -- assign to a global variable
print(myLongNamedGlobalVeriable) --> nil   (wtf!)

并没有意识到你犯了错字。在JavaScript中,ReferenceError会对此提供保护。