Javascript:父/子对象实例化的顺序
Javascript: order of parent/child object instantiation
我是 JavaScript 的新手,想更多地了解它实例化父/子对象的顺序。更具体地说,我想从编译器/浏览器的角度理解以下代码片段。
var parent = {
child: {
field1: "value1",
field2: "value2"
},
someOtherField: parent.child.field1, // => Error
someOtherField: this.child.field1 // => Error
};
上面代码段中的两个Error
行将生成相同的错误
Uncaught TypeError: Cannot read property 'field1' of undefined
因此,当浏览器查看someOtherField
行时,似乎parent.child
仍然undefined
,因此parent.child.field1
是非法的。有人可以分享一些关于为什么会发生这种情况的见解,以及浏览器尝试使用上述代码片段运行的确切指令顺序是什么?谢谢!
在代码中(一次处理一个问题):
var parent = {
child: {
field1: "value1",
field2: "value2"
},
someOtherField: parent.child.field1 // => Error
};
在执行任何代码之前,将创建变量父级并将其初始化为未定义(所谓的"提升")。一旦执行开始,对渐进结果的检查似乎是首先将对象分配给父对象,然后解析内部属性。
所以第一条错误消息是这样的:
TypeError: undefined is not an object (evaluating 'parent.child.field1')
因为父级是一个对象。从此结果中,无法判断父属性是否具有子属性,因为它可能具有初始化为 undefined 的子属性,或者它可能根本没有子属性。无论哪种方式,parent.child
解析为 undefined,尝试解析 undefined 的属性都会返回类型错误。
请注意,给定:
var parent = {
one: 'one',
two: parent.one
}
console.log(parent.one, parent.two) // one undefined
可以看出,在将值分配给 parent.two 时,parent.one 是未定义的。
至于:
someOtherField: this.child.field1
this的值将是全局对象(浏览器中的窗口),并且它没有子属性,因此您会收到类似的错误:
TypeError: undefined is not an object (evaluating 'this.child.field1')
由于没有全局子项,因此 this.child 返回未定义,尝试解析未定义的属性会引发类型错误。
另请注意:
someOtherField: this.parent.child.field1
相当于:
someOtherField: parent.child.field1
并抛出相同的错误。
底线是,不应尝试分配部分完成的对象的属性。我确定 ECMA-262 中有适当的参考,需要一点时间才能找到它。
这与父/子对象实例化无关。它与吊装有关。
JavaScript 中的所有声明都被提升。请记住,变量声明和变量定义是两个不同的东西。例如,我们可以使用 var x
声明一个变量x
。我们使用x = someValue
定义x
。我们可以将变量声明和变量定义组合到一个构造中,作为var x = someValue
。但是,我们仍在声明变量,然后定义它。
正如我所说,JavaScript 中的所有声明都被提升(即它们被提升到声明它们的函数范围的顶部)。例如,考虑:
alert(x); // declared but not defined (undefined)
var x = null;
alert(x); // declared and defined (null)
在这里,变量声明var x
被提升到范围的顶部。默认情况下,已声明但尚未定义的变量的值undefined
。
将上面的代码与:
try {
alert(x);
x = null;
alert(x);
} catch(e) {
alert(e); // ReferenceError: x is not defined
}
在这里我们没有宣布x
.因此x
不会被吊起。因此,当我们尝试打印x
的值时,我们会得到一个 ReferenceError
.请注意,它不是undefined
,因为我们甚至没有声明它。
代码中发生了什么
现在让我们考虑一下您的代码:
var parent = {
child: {
field1: "value1",
field2: "value2"
},
someOtherField: parent.child.field1 // => Error
someOtherField: this.child.field1 // => Error
};
这与
:var parent; // hoisted; undefined
parent = {
child: {
field1: "value1",
field2: "value2"
},
someOtherField: parent.child.field1 // => Error
someOtherField: this.child.field1 // => Error
};
在定义parent
之前,它是undefined
。因此parent.child.field1
undefined.child.field1
这是一个错误。此外,this
不指向对象文字。您的错误是,直到将对象文字分配给变量之后(即在计算parent.child.field1
之后),才定义parent
。
您可以做的是:
var parent = {
child: {
field1: "value1",
field2: "value2"
}
};
parent.someOtherField = parent.child.field1;
希望有帮助。
- 如何在GoogleWeb工具包(GWT)中从JSNI调用接口(实例化)
- 如何在用户输入时实例化数组
- 在requirejs中共享实例化对象
- Mongoose TypeError:实例化模式类型的对象时,对象不是函数
- Angular重命名模块后未能实例化模块
- Backbone relational无法实例化两个RelationalModel对象
- 我应该如何用javascript实例化这个日期
- AngularJS出错-无法实例化模块
- 谷歌地图重叠MarkerSpiderfier实例化问题
- 未捕获错误:由于,[$injector:moduler]未能实例化模块polmgr
- ngRoute不是因果报应实例化的
- JavaScript 中的动态实例化
- 在文本框上绑定谷歌地点自动完成,而无需实例化谷歌地图
- UI5 路由不实例化视图
- 在 JavaScript 中,当我们实例化派生对象时,原型的函数隐藏在哪里
- 仅在需要时实例化聚合物元素
- 角度 JS 控制器未实例化
- 如何理解“当类实例化时,JavaScript静态方法也是不可调用的”
- Javascript:父/子对象实例化的顺序
- JavaScript:定义函数和实例化对象的顺序