Class 的继承

2020-09-21  本文已影响0人  懂会悟

1、extends

ES6通过extends关键字实现继承。ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。因此,如果子类显示定义了constructor方法,那么必须在constructor方法中显示调用super方法,如果子类没有定义constructor方法,这个方法会被默认添加

// 子类未显示定义constructor方法
class ColorPoint extends Point {
}

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

(显示定义子类的构造函数)在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。

父类的静态方法,也会被子类继承

class A {
  static hello() {
    console.log('hello world')
  }
}

class B extends A {
}

B.hello()  
// hello world

2、super

super关键字的用途

super当作函数使用时, 代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。作为函数时,super()只能用在子类的构造函数之中。

class A {}

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

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

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

class A {
  p() {
    return 2
  }
}

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

let b = new B()

上面代码中,子类B当中的super.p(),就是将super当作一个对象使用。这时,super在普通方法之中,指向A.prototype,所以super.p()就相当于A.prototype.p()。

由于super作为对象使用时指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的,但是可以通过this获取

class A {
  constructor() {
    this.p = 2
  }
}

class B extends A {
  get m() {
    console.log('super', super.p) 
    <!--undefined-->
    console.log('this', this.p)
    // 2
  }
}

let b = new B()
b.m 

在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。

class A {
  constructor() {
    this.x = 1
  }
  print() {
    console.log(this.x)
  }
}

class B extends A {
  constructor() {
    super()
    this.x = 2
  }
  m() {
    super.print()
  }
}

let b = new B()
b.m()
// 2

在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例。

class A {
  constructor() {
    this.x = 1
  }
  static print() {
    console.log(this.x)
  }
}

class B extends A {
  constructor() {
    super()
    this.x = 2
  }
  static m() {
    super.print()
  }
}

B.x = 3
B.m()
// 3

上一篇 下一篇

猜你喜欢

热点阅读