我正在尝试弄清JavaScript中的超级(super)是如何工作的。 我有一些想法,但不确定它们的准确性,所以需要帮助。
class A {
}
class B extends A {
constructor() {
super();
}
}
class C extends B {
constructor() {
super();
}
}
new C
在上述代码中,'new'运算符创建一个对象并将其链接到构造函数C的原型,构造函数C的隐藏属性'thisArg'现在指向新创建的对象。
+---------------------+
| function object |
+---------------------+
| - code |
+---------------------+
| - outerScope |
+---------------------+
| - thisArg |
+---------------------+
| - [[Prototype]] |
+---------------------+
| + prototype |
+---------------------+
| + length |
+---------------------+
| + name |
+---------------------+
注意:隐藏属性“thisArg”可以在每个函数调用中通过隐式(使用访问运算符“.”和“[]”)、显式(使用.call、.apply、.bind方法)或“new”运算符进行更改。
词法环境的“this”引用将指向无论函数隐藏属性“thisArg”指向何处。
回到过程中,构造函数C被执行,然后super将新创建的对象传递给B构造函数,构造函数B的隐藏属性"thisArg"现在指向新创建的对象。
构造函数B也是如此,它被执行并且super将新创建的对象传递给A构造函数,其中构造过程开始。
当A完成构造时,它将对象传递给B,然后B将更多的插槽添加到结构体中,并传递给C。
最后,C结束构造并返回构造好的对象。
所以基本上,新创建的对象首先从构造函数冒泡到构造函数,然后向下滴漏?
super
部分和规范了吗?值得指出的是,在执行new C
时,构造函数内部的this
是C
的一个实例(永远不是A
或B
),并且只有在链中最后一个super
调用之后才能访问this
。 - Sebastian SimonA
时才会创建对象。上面的代码对于使用function
的旧方法来说是接近的,但对于使用class
的情况则不然。 - T.J. Crowderthis
在调用C
之前被创建,这是不正确的。 - T.J. Crowderthis
是绑定在(非箭头)函数环境记录和模块环境记录中的。还有一个叫做thisArgument
的不同东西,它是... - T.J. Crowder