javascript 面向对象编程中 super() 构造函数和子类方法的执行顺序是什么?
What is the order of executing super() constructor and subclass methods in javascript object oriented programming?
为什么在 subclass 的 render()
方法中 this
未定义?
为什么baseclass构造函数里面的this
引用了subclass创建的对象?我想知道这里的执行顺序。
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
所以顺序如下:
derivedClass
构造函数在您执行 new derivedClass();
时被调用
- 它调用
baseClass
构造函数
- 数据成员填充了
baseClass
“拥有”的内容
- 尽管这些方法属于
derivedClass
,这就是为什么当从 baseClass
构造函数调用渲染时您会看到“derivedClass rendered”。
- 添加
derivedClass
的数据成员
derivedClass
构造函数再次调用 render
。
这有点违反直觉,特别是如果你有 C++、Java 等 OOP 背景。我认为这就是为什么有些人试图避免 类 和 this
在 Java 完整的脚本中。
为什么在 subclass 的 render()
方法中 this
未定义?
为什么baseclass构造函数里面的this
引用了subclass创建的对象?我想知道这里的执行顺序。
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
所以顺序如下:
derivedClass
构造函数在您执行new derivedClass();
时被调用
- 它调用
baseClass
构造函数 - 数据成员填充了
baseClass
“拥有”的内容 - 尽管这些方法属于
derivedClass
,这就是为什么当从baseClass
构造函数调用渲染时您会看到“derivedClass rendered”。 - 添加
derivedClass
的数据成员 derivedClass
构造函数再次调用render
。
这有点违反直觉,特别是如果你有 C++、Java 等 OOP 背景。我认为这就是为什么有些人试图避免 类 和 this
在 Java 完整的脚本中。