为什么可以在内部函数成员中访问对象引用,而不是在内部属性成员中访问?

时间:2015-02-27 16:01:01

标签: javascript scope

例如,这失败了TypeError: Cannot read property 'a' of undefined

var obj = {
  a: 23,
  b: obj.a,
};

虽然这有效:

var obj = {
  a: 23,
  getA: function() {
    return obj.a;
  }
};

奖金问题

那为什么不抛出ReferenceError

var obj = {
  a: 23,
  b: obj
};

毕竟,obj仍然不存在!如果我试图在其他地方访问一个尚未定义的东西,它会抛出ReferenceError

3 个答案:

答案 0 :(得分:4)

您无法访问尚未构建的对象上的对象成员。

在第二个示例中,函数getA在对象obj创建后被称为,因此可以访问。

答案 1 :(得分:2)

第二个示例中的内容是闭包。函数内部的变量引用(也就是闭包)是指变量本身,而不是定义函数时变量的值。

观察:



var a;

function loga() {
  console.log(a);
}

loga(); // undefined

a = 3;

loga(); // 3

a = "hello";

loga(); // hello




您的示例中发生的事情完全相同。在 obj已经有值之后执行函数,所以一切正常。

正如Felix Kling所指出的那样,只要在范围内声明某处,声明变量的位置并不重要。这通俗地称为"变量提升"。

如果你真的想要,你甚至可以这样做:



function loga() {
  console.log(a);
}

var a = 3;

loga(); // 3




答案 2 :(得分:1)

  

那么为什么不抛出一个ReferenceError:

var obj = {
  a: 23,
  b: obj
};
     

毕竟,obj还不存在!如果我试图在其他地方访问一个尚未定义的东西,它会抛出一个ReferenceError。

由于提升变量 obj存在。它还没有。您的示例等同于

var obj; // declaration is hoisted to the top of the scope
obj = {
  a: 23,
  b: obj
};

obj存在但具有(默认)值undefined