理解 es6 class 中的 super

super 关键字用于访问和调用一个对象的父对象上的函数。

class

ES6 的 class 并没有为 JavaScript 引入新的面向对象的继承模型,实质上是 JavaScript 现有的基于原型继承的语法糖。

1
2
3
4
5
6
7
8
9
10
11
// ES6
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}

toString() {
return '(' + this.x + ',' + this.y + ')';
}
}

等同于:

1
2
3
4
5
6
7
8
9
// ES5
function Point(x, y) {
this.x = x;
this.y = y;
}

Point.prototype.toString = function() {
return '(' + this.x + ',' + this.y + ')';
}

constructor 方法是一个特殊的方法,这种方法用于创建和初始化一个由 class 创建的对象。一个类只能拥有一个名为 “constructor”的特殊方法。如果类包含多个 constructor 的方法时会报错,如果没有显示定义 constructor 方法,会默认添加一个。

一般 constructor 方法返回实例对象 this ,但是也可以指定 constructor 方法返回一个全新的对象,让返回的实例对象不是该类的实例。

super关键字

super 关键字有两种用法,下面的是 MDN 上给出的语法结构:

1
2
3
4
5
super([arguments]);
// 调用 父对象/父类 的构造函数

super.functionOnParent([arguments]);
// 调用 父对象/父类 上的方法

调用 父对象/父类 的构造函数

1
2
3
4
5
6
7
class B extends A {
constructor(width) {
// 相当于 A.prototype.constructor.call(this, length)
super(length)
this.name = 'Job'
}
}

注意:

  • 使用了 extends 关键字并指定了 constructor 函数时,必须执行一次 super()
  • 此时的 super 作为函数使用;
  • 必须写在子类(B)的 constructor 之内;
  • 必须写在 this 之前.

调用 父对象/父类 上的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A {
constructor() {
this.name = 'Frank'
}
sayName() {
return `i'm ${this.name}`
}
}

class B extends A {
constructor() {
super()
this.name = 'Job'
}
sayMyName() {
// 相当于 A.prototype.sayName.call(this)
return super.sayName()
}
}

let C = new B()
C.sayMyName() // "i'm Job"

注意:

  • 此时 super 作为对象使用;