返回

ES6 构造函数中给 super 赋值的奥秘:揭示父类实例属性修改的本质

javascript

ES6 中构造函数中给 super 赋值的奥秘

导语

在 ES6 的类语法中,子类构造函数必须通过调用父类构造函数来初始化,这可以通过 super 实现。然而,在给 super 赋值时,看似是在操作子类实例,但实际上却与父类紧密相关。本文将深入探究这一机制,揭示其缘由和意义。

理解继承关系

在面向对象编程中,子类继承了父类的属性和方法。当实例化子类时,它将创建一个包含父类属性和方法副本的新对象。在 ES6 中,super 充当了通往父类构造函数和属性的桥梁。

赋值 super 的本质

当在构造函数中给 super 赋值时,实质上是在调用父类构造函数时,给父类实例的属性赋值。这是因为 super 指向父类的一个新实例,该实例在子类构造函数执行之前就已经被创建。

示例代码

class A {
  constructor() {
    this.x = 1;
  }
}
class B extends A {
  constructor() {
    super(); // 调用父类构造函数
    this.x = 2;
    super.x = 3; // 给父类实例的属性赋值
  }
}

在这个示例中,当实例化 B 类时,首先会调用父类 A 的构造函数,创建一个 A 类的实例。此时,super() 指向这个实例。随后,super.x = 3 将 3 赋值给了父类实例的 x 属性。

superthis 的区别

superthis 是两个截然不同的

  • super 指向父类的一个新实例。
  • this 指向当前类的实例。

因此,this.xsuper.x 并不会指向同一个属性。this.x 指向当前类的 x 属性,而 super.x 指向父类的 x 属性。

示例输出

const b = new B();
console.log(super.x); // undefined
console.log(this.x); // 3

在示例输出中,console.log(super.x) 输出 undefined,因为 super.x 指向父类实例的 x 属性,而该属性在父类构造函数中并未赋值。而 console.log(this.x) 输出 3,因为 this.x 指向当前类的 x 属性,该属性在构造函数中赋值为 3。

结论

super 赋值的本质是通过父类构造函数间接赋值给父类实例的属性。这有助于理解子类继承父类的机制,并为进一步探索面向对象编程奠定基础。

常见问题解答

  1. 为什么在子类构造函数中必须调用父类构造函数?
    为了初始化父类属性,并建立继承关系。
  2. super 赋值的目的是什么?
    间接给父类实例的属性赋值。
  3. superthis 有什么区别?
    super 指向父类实例,而 this 指向当前类实例。
  4. 什么时候可以使用 super
    在子类构造函数中,用于调用父类构造函数和访问父类属性。
  5. 给父类实例的属性赋值的目的是什么?
    覆写或扩展父类属性,以满足子类的特定需求。