为什么JavaScript声明变量在初始化之前在全局对象中?

时间:2013-05-02 14:14:05

标签: javascript function variables scope global-variables

我偶然发现了一个我无法解释的JavaScript变量行为。

根据JS docs on var keyword

  

用var声明的变量的范围是封闭函数   或者,对于在函数外声明的变量,全局范围(   绑定到全局对象)。

众所周知,全局变量成为全局对象的属性 - 浏览器环境中的“窗口”和node.js中的“全局” 这意味着如果在函数内使用'var'关键字声明变量,它将变为本地变量并且不会进入全局对象。

这个例子证明了这一点:

(function(){
    var t = 1;
    console.log(t in window, t); // outputs: false 1
}());

jsfiddle link

到目前为止一切顺利。但是,如果变量未初始化,它确实成为窗口对象的属性,尽管它在函数范围内。

(function(){
    var t;
    console.log(t in window, t); // outputs: true undefined
}());

jsfiddle link

为什么会这样?我在哪里可以了解这种行为的细节?常规教程似乎没有涵盖这一点。

提前致谢。

[编辑]: 感谢Pointy很明显,现在范围按预期工作。我对'in'运算符行为的理解错误。根据{{​​3}},它将左手操作数强制转换为数字或字符串,并在右侧对象中查找此类索引或属性名称。 所以在示例中,它等于

'1' in window

这是假的

在示例二中它是

'undefined' in window

这是真的。

2 个答案:

答案 0 :(得分:4)

问题是您的测试代码错误地使用了in运算符。它实际测试的是“{undefined”这个名字是在window中定义的,而不是“t”。为什么?因为in的左侧操作数被强制转换为字符串。因为“t”是undefined,所以它被强制转换为字符串“undefined”,实际上该属性名称存在于全局上下文中。

将测试更改为

console.log("t" in window, t);

答案 1 :(得分:2)

访问由

声明的变量
var t;

给你:

console.log(t);
undefined

console.log(undefined === t)
true

undefined是window

的属性
console.log(undefined in window);