如果“窗口”,检查“窗口”中是否存在属性将失败。没有预先

时间:2013-07-03 22:17:09

标签: javascript

我想检查窗口中是否存在属性,所以我这样做了:

此代码有效:

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");
}

令我惊讶的是它不起作用。我的问题是,如果我不添加窗口,它为什么不起作用?

2 个答案:

答案 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

另一方面,如果它的对象发生以下情况:

  
      
  1. 让base成为调用GetBase(V)的结果。
  2.   
  3. 设O为ToObject(base)。
  4.   
  5. 设desc是调用属性名为P的O的[[GetProperty]]内部方法的结果。
  6.   
  7. 如果未定义desc,请返回undefined。
  8.   

所以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