javascript - javascript面向对象编程中super()构造函数和子类方法的执行顺序是什么?

标签 javascript class object constructor this

为什么子类内部的 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

所以顺序如下:

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

这有点违反直觉,特别是如果您来自 C++、Java 等 OOP 背景。我认为这就是为什么有些人试图在 JavaScript 中完全避免类和 this 的原因。

关于javascript - javascript面向对象编程中super()构造函数和子类方法的执行顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70288878/

相关文章:

javascript - 如何仅在上次调用后返回类方法结果

java - 我应该给一个只有 getter 的 Java 类起什么名字?

c++ - 使用引用修改 const 对象

javascript - 如何使用 php array_chunk 和 javascript 过滤器将项目保留在一行中?

javascript - 如何清除剑道组合框的值

javascript - 在 Watson Assistant 中添加和编辑 JSON 数组

javascript - KnockoutJS 中的 jQuery

Java 套接字 : How to send and serialize object between multiple applications

javascript - 在javascript中使用变量的值来访问JSON对象

javascript - javascript中遍历一个对象并转换为特定格式