让我们说,“x”是一个从未定义的变量,所以它应该是未定义的。在以下场景中:
1)
if(x){//do something}
//ReferenceError: x is not defined
2)
if(window.x){//do something}
//worked as expected
据我所知,在这里的浏览器环境中,x应该与window.x相同,是否有人可以帮助指出这里不同行为的原因?
答案 0 :(得分:4)
x
只有window.x
才会被声明(在全局范围内,自然而然)。这可以通过全局范围中的显式var
语句或任何范围内没有var
的简单赋值(被认为是隐式全局声明)来完成:
var a; // declares global a
function foo() {
b = 10; // declares (implict) global b
}
a
和b
在网络浏览器中也可以window.a
和window.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 x
或var 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会对此提供保护。