Skip to content

constructor 方法

constructor 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。一个类必须有 constructor() 方法,如果没有显示定义,一个空的 constructor() 方法会被默认添加。

js
class Point {

}

// 等价于
class Point {
  constructor() {}
}

上面代码中,定义了一个空的类Point,JavaScript 引擎会自动为它添加一个空的constructor()方法。

constructor()方法默认返回实例对象(即this)

1 继承(子类)中的constructor方法

如果子类显式的定义了 constructor 方法,则必须在其中调用 super 方法,否则新建实例时会报错。

js
class Point { /* ... */ }

class ColorPoint extends Point {
  constructor() {
  }
}

let cp = new ColorPoint(); // ReferenceError

上面代码中,ColorPoint继承了父类Point,但是它的构造函数没有调用super方法,导致新建实例时报错。

如果子类没有定义constructor方法,这个方法会被默认添加,代码如下。

js
class ColorPoint extends Point {
}

// 等同于
class ColorPoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错

js
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    this.color = color; // Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
    super(x, y);
    this.color = color; // 正确
  }
}

2 super

2.1 代表父类的构造函数

作为函数调用时,代表父类的构造函数。作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错。

js
class A {}

class B extends A {
  constructor() {
    super();
  }
}

super 虽然代表了父类 A 的构造函数,但是 super 内部的 this 指的是 B 的实例,因此 super() 在这里相当于 A.prototype.constructor.call(this)。

2.2 代表父类或者父类的原型对象

super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

js
class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();