为什么子类内部的 render()
方法中的 this
未定义?
为什么基类构造函数中的this
引用的是基于子类创建的对象?我想知道这里的执行顺序。
class baseClass {
constructor() {
this.render(); // why does "this" (not this.render()) refer to the created object based on derivedClass?
}
render() {
console.log("won't get executed.");
}
}
class derivedClass extends baseClass {
foo = "foo"
constructor() {
super();
console.log(this);
}
render() {
console.log(this.foo); // why is "this" undefined?
alert("rendered");
}
}
new derivedClass;
最佳答案
为了更好地理解它是如何工作的,您可以稍微更改一下代码:
class baseClass {
bar = 'bar';
constructor() {
console.log(
`In baseClass constructor this is ${JSON.stringify(this, null, 2)}`
);
this.render(); // why does "this" (not this.render()) refer to the created object based on derivedClass?
}
render() {
console.group();
console.log(this);
console.log('baseClass rendered');
console.groupEnd();
}
}
class derivedClass extends baseClass {
foo = 'foo';
constructor() {
super();
console.log(
`In derivedClass constructor this is ${JSON.stringify(this, null, 2)}`
);
this.render();
}
render() {
console.group();
console.log(this);
console.log('derivedClass rendered');
console.groupEnd();
}
}
new derivedClass();
它将输出:
In baseClass constructor this is {
"bar": "bar"
}
derivedClass { bar: 'bar' }
derivedClass rendered
In derivedClass constructor this is {
"bar": "bar",
"foo": "foo"
}
derivedClass { bar: 'bar', foo: 'foo' }
derivedClass rendered
所以顺序如下:
衍生类
构造函数在执行new衍生类();
时被调用
- 它调用
baseClass
构造函数 - 数据成员由
baseClass
“拥有”的内容填充 - 尽管这些方法属于
衍生类
,这就是为什么当从baseClass
构造函数调用 render 时,您会看到“已渲染衍生类”。 - 添加
衍生类
的数据成员 衍生类
构造函数再次调用render
。
这有点违反直觉,特别是如果您来自 C++、Java 等 OOP 背景。我认为这就是为什么有些人试图在 JavaScript 中完全避免类和 this
的原因。
关于javascript - javascript面向对象编程中super()构造函数和子类方法的执行顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70288878/