Skip to main content

14 根类

定义自己的构建过程

JavaScript 使用原型继承来搭建自己的面向对象的继承体系,在这个过程中诞生了两种方法:

  1. 使用一般函数的构造器;
  2. 使用 ECMAScript 6 之后的类。

父类并不知道子类X,却又需要X.prototype来为实例this设置原型。

// 在JavaScript内置类Date()中可能的处理逻辑
function _Date() {
this = Object.Create(Date.prototype, { _internal_slots });
Object.setPrototypeOf(this, new.target.prototype);
...
}
  1. 依据父类的原型,也就是 Date.prototype 来创建对象实例 this,因为它是父类创建出来的;
  2. 置 this 实例的原型为子类的 prototype,也就是 new.target.prototype,因为它最终是子类的实例。

是super()在传递这个new.target参数。

关于隐式的构造方法

如果用户代码没有声明构造方法,ECMAScript 规范约定,引擎需要向用户代码中插入一段硬代码。即帮你写一个缺省的构造方法,然后引擎为这个硬代码的代码文本动态地生成一个“构造方法”声明,最后再将它初始化为类。

// 如果在class声明中有extends XXX
class MyClass extends XXX {
// 自动插入的缺省构造方法
constructor(...args) {
super(...args);
}
...
}

// 如果在class声明中没有声明extends
class MyClass {
// 自动插入的缺省构造方法
constructor() {}
...
}

非派生类是不用调用 super() 的

在传统的构造函数和非派生类的构造方法中,一样是有new.target的。如果是不使用super()调用的类或构造器函数,那么可以让它做根类(祖先类)。