2021.05.26(Class 的继承)

Class 可以通过 extends  关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便
很多。

 

1.  class Point {
2.  }
3.
4.  class ColorPoint extends Point {
5.  }

 

上面代码定义了一个 ColorPoint  类,该类通过 extends  关键字,继承了 Point  类的所有属性
和方法。但是由于没有部署任何代码,所以这两个类完全一样,等于复制了一个 Point  类。下面,我
们在 ColorPoint  内部加上代码。

1.  class ColorPoint extends Point {
2.  constructor(x, y, color) {
3.  super(x, y); // 调用父类的constructor(x, y)
4.  this.color = color;
5.  }
6.
7.  toString() {
8.  return this.color + ' ' + super.toString(); // 调用父类的toString()
9.  }
10.  }

上面代码中, constructor  方法和 toString  方法之中,都出现了 super  关键字,它在这里表
示父类的构造函数,用来新建父类的 this  对象。

子类必须在 constructor  方法中调用 super  方法,否则新建实例时会报错。这是因为子类自己
的 this  对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对
其进行加工,加上子类自己的实例属性和方法。如果不调用 super  方法,子类就得不到 this  对
象。

1.  class Point { /* ... */ }
2.
3.  class ColorPoint extends Point {
4.  constructor() {
5.  }
6.  }
7.
8.  let cp = new ColorPoint(); // ReferenceError

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

ES5 的继承,实质是先创造子类的实例对象 this  ,然后再将父类的方法添加到 this  上面
( Parent.apply(this)  )。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,
加到 this  上面(所以必须先调用 super  方法),然后再用子类的构造函数修改 this  。

如果子类没有定义 constructor  方法,这个方法会被默认添加,代码如下。也就是说,不管有没有
显式定义,任何一个子类都有 constructor  方法。

1.  class ColorPoint extends Point {
2.  }
3.
4.  // 等同于
5.  class ColorPoint extends Point {
6.  constructor(...args) {
7.  super(...args);
8.  }
9.  }

另一个需要注意的地方是,在子类的构造函数中,只有调用 super  之后,才可以使用 this  关键
字,否则会报错。这是因为子类实例的构建,基于父类实例,只有 super  方法才能调用父类实例。

1.  class Point {
2.  constructor(x, y) {
3.  this.x = x;
4.  this.y = y;
5.  }
6.  }
7.
8.  class ColorPoint extends Point {
9.  constructor(x, y, color) {
10.  this.color = color; // ReferenceError
11.  super(x, y);
12.  this.color = color; // 正确
13.  }
14.  }

上面代码中,子类的 constructor  方法没有调用 super  之前,就使用 this  关键字,结果报错,而放在 super  方法之后就是正确的。

 

2021-05-28  17:22:32

posted @ 2021-05-28 17:23  铁打的代码流水的bug  阅读(47)  评论(0)    收藏  举报