例如,这失败了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
!
答案 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
。