在javascript中访问对象和变量的属性

时间:2012-09-18 21:31:46

标签: javascript

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

例如,此案例返回undefined值:

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

Foo();

但是,在另一个例子中,javascript抛出异常:

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

Foo();

ReferenceError:未定义bar

3 个答案:

答案 0 :(得分:3)

由于JavaScript中的每个对象都是字典,也称为其他语言的映射,this.bar等同于this['bar'],即通过键访问值。在大多数语言中,例如在Java中,返回nullNULLundefined允许您有条件地创建此插槽(如果它尚不存在),而不处理异常或任何其他副作用。

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

答案 1 :(得分:1)

属性解析与标识符解析根本不同。简单的答案是,ECMA-262指定尝试读取不存在的变量将引发错误,而尝试读取不存在的对象属性则不会,它只返回特殊的undefined值。

为了解决这个问题,你需要先咨询开发JavaScript的Brendan Eich,ECMA-262就是基于它的。然而,一个合理的猜测是Brendan希望将JavaScript变成一种松散打字的简单语言,而不是像以下那样做:

if ( 'foo' in obj) {
  /* do something with obj.foo */
}

每当您第一次想要访问某个属性时,该语言就可以容忍访问未定义属性的尝试。

另一方面,对变量应用相同的方法会产生比解决更多的问题,因此可以使用typeof来查看是否存在标识符:

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

否则,属性和标识符解析非常相似。不同之处在于,第一个从对象开始,沿着一串内部[[Prototype]]对象(继承链),最后到达null对象,而变量分辨率从局部变量对象沿着一个字符串进行属于外部上下文(作用域链)的类似对象的全局对象。

答案 2 :(得分:0)

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

Foo();

也会给你undefined

this.bar表示this["bar"]