我想检查窗口中是否存在属性,所以我这样做了:
此代码有效:
if (window.foo) {
alert("exists");
}
else {
alert("doesn't exist");
}
输出:
不存在
我认为下一个代码也应该起作用,因为据我所知,当你定义变量并且你不在函数内部时,它们被创建为“window”对象的属性,所以这应该是等价的:
if (foo) { //it fails here "foo is not defined"
alert("exists");
} else {
alert("doesn't exist");
}
令我惊讶的是它不起作用。我的问题是,如果我不添加窗口,它为什么不起作用?
答案 0 :(得分:7)
第一个版本是property access,它找不到属性,因此返回undefined。第二个是尝试访问未定义的变量。
使用elclanrs建议的内容:
if(typeof foo === "undefined"){
alert("exists");
} else {
alert("doesn't exist");
}
这是因为语言规范中指定了GetValue
。
0.3。如果是IsUnresolvableReference(V),则抛出ReferenceError异常。
这是if(foo)
案例中发生的情况,因为之前未定义foo
。
另一方面,如果它的对象发生以下情况:
- 让base成为调用GetBase(V)的结果。
- 设O为ToObject(base)。
- 设desc是调用属性名为P的O的[[GetProperty]]内部方法的结果。
- 如果未定义desc,请返回undefined。
醇>
所以window.foo
返回原始语言值undefined
,这是假的。
答案 1 :(得分:1)
将Window
对象视为“巨型闭包”,它封装了所有其他对象。现在考虑一下:
var ext = "test";
function myScope() {
var ext = "foo"; //new variable in myScope's scope
console.log(ext); //foo
}
function changeExt() {
ext = "bar";//ext is not defined in this scope, so JS will look in the chain of scopes and set the value to the defined var in the global scope
console.log(ext);
}
myScope();
console.log(ext); //test
changeExt();
console.log(ext); //ext has been changed by changeExt to bar
为什么会这样?因为您使用window.property
来尝试访问window
对象的未定义属性,而不是引用未声明的 var。
如果你试图在全局闭包中使用var
关键字而做同样的事情,你将得到相同的结果,因为它是范围链的最后一个。
现在让我们把它想象成一个巨大的物体:
var myObj = {prop: 'defined'};
假设myObj
是“全局对象”,如果您尝试访问prop
,JS会将您重定向到myObj.prop
(或者它会尝试执行此操作),如果属性(例如命名)foo
未声明您将获得ReferenceError
。