2012-09-18 57 views
2

为什么当我尝试访问不存在的变量时,JavaScript会抛出异常,但是当我尝试访问对象中不存在的属性时,javascript会返回undefined值?在javascript中访问对象vs变量的属性

例如,这种情况下返回一个undefined值:

function Foo(){ 
    console.log(this.bar); 
} 

Foo(); 

但是,在该其他例子中,JavaScript的抛出异常:

function Foo(){ 
    console.log(bar); 
} 

Foo(); 

的ReferenceError:未定义酒吧

+2

注意'undefined'是一个值,而不是一个对象。 – nnnnnn

+0

感谢您的更正@nnnnnn – Samuel

回答

3

由于JavaScript中的每个对象都是字典,也称为其他语言的地图,this.bar相当于this['bar'],我.e。通过键访问值。在大多数语言中,例如在Java中,返回null,NULLundefined允许您有条件地创建该槽,如果该槽尚不存在,而不处理异常或任何其他副作用。

但是,如果您只是在没有指定bar的上下文的情况下编写console.log(bar),则无法创建合理的模式,其中返回undefined具有语义含义。有多个上下文,其中一些是动态的,如浏览器中的全局上下文window,其中bar可能在运行时期间定义,所以它不能是编译时错误(与Java或C++相反)。因此,当变量名称无法解析时抛出运行时异常。

0
function Foo(){ 
    console.log(window.bar); 
} 

Foo(); 

也会给你undefined

this.bar装置this["bar"]

1

属性的分辨率是根本不同的,以标识符解析。微不足道的答案是,ECMA-262指定试图读取一个不存在的变量会抛出一个错误,而试图读取一个不存在的对象属性不会,它只返回特殊的undefined值。

为了找到原因,您需要首先开发基于ECMA-262的JavaScript的Brendan Eich。然而,合理的猜测是,布兰登想让JavaScript和弱类型的简单语言,因此而不必像做:

if ('foo' in obj) { 
    /* do something with obj.foo */ 
} 
您要访问的属性首次每次

,语言被允许访问未定义的属性。

。另一方面,运用同样的办法变量,就会产生更多的问题比解决的,所以如果标识符存在typeof可以用来查看:

if (typeof foo != 'undefined') { 
    /* ok to use foo */ 
} 

否则,财产和标识的分辨率是非常相似。不同之处在于,第一个从对象开始,沿着一串内部对象(继承链),最后到达对象null,而可变分辨率从局部变量对象沿着属于外部上下文的类似对象的字符串继续进行(范围链)到全局对象。