我偶然发现了一个我无法解释的JavaScript变量行为。
根据JS文档中的var关键字:
用var声明的变量的作用域是封闭函数或者,对于在函数外部声明的变量,全局作用域(其中(绑定到全局对象)。
众所周知,全局变量成为全局对象的属性——在浏览器环境中是'window',在node.js中是'global'这意味着,如果一个变量在函数中使用'var'关键字声明,它将成为局部变量,而不会进入全局对象。
这个例子证明了这一点:
(function(){
var t = 1;
console.log(t in window, t); // outputs: false 1
}());
jsfiddle联系
到目前为止一切顺利。然而,如果变量没有初始化,它就会成为窗口对象的属性,尽管它在函数作用域中。
(function(){
var t;
console.log(t in window, t); // outputs: true undefined
}());
jsfiddle联系
为什么会发生?我在哪里可以了解到这种行为的细节?常规教程似乎没有涉及到这一点。
提前感谢。
[编辑]:多亏了Pointy,现在很清楚scope工作如预期。我只是对"in"操作符的行为有一个错误的理解。根据'in'文档,它将左手操作数强制转换为数字或字符串,并在右手对象中查找此类索引或属性名称。在第一个例子中它等于
'1' in window
为假
在第二个例子中是
'undefined' in window
问题是您的测试代码错误地使用了in
操作符。它实际上测试的是名称"undefined"是否在window
中定义,而不是"t"。为什么?因为in
的左操作数被强制为字符串。因为"t"是undefined
,所以它被强制为字符串"undefined",并且该属性名称确实存在于全局上下文中。
将测试更改为
console.log("t" in window, t);
访问由
声明的变量var t;
给你:
console.log(t);
undefined
console.log(undefined === t)
true
undefined是window
的一个属性console.log(undefined in window);