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

所以顺序如下:

  1. derivedClass 构造函数在您执行 new derivedClass();
  2. 时被调用
  3. 它调用 baseClass 构造函数
  4. 数据成员填充了baseClass“拥有”的内容
  5. 尽管这些方法属于 derivedClass,这就是为什么当从 baseClass 构造函数调用渲染时您会看到“derivedClass rendered”。
  6. 添加derivedClass的数据成员
  7. derivedClass 构造函数再次调用 render

这有点违反直觉,特别是如果你有 C++、Java 等 OOP 背景。我认为这就是为什么有些人试图避免 类 和 this 在 Java 完整的脚本中。