欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6中类的继承

程序员文章站 2022-07-16 21:53:54
...

Class的继承

class通过extends关键字来实现继承。比es5中的各种继承相比要方便很多。

class A {
    constructor(val){
        this.val=val
    }
}
class Aa extends A{
    constructor(val){
        super(val)
    }
    sayA(){
        return this.val;
    }
}
var aa = new Aa('a')
console.log(aa.sayA()) //a

super关键字表示父类的构造函数,用来新建父类的this对象。子类必须在constructor中调用super方法来得到父类中的实例和方法,如果没有调用super方法,在新建实例时会报错。

ES5与ES6中继承的区别
在ES5中,是先创造了子类的实例对象this,然后将父类的属性、方法通过apply()或者call()添加到this中。

ES6中的继承则不同,是先将父类的实例对象的属性和方法添加到this中(super方法),然后再用子类的构造函数修改this

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

class A {
    constructor(val){
        this.val=val
    }
}
class Aa extends A{
    constructor(val,aa){
        this.aa=aa  //报错,不能写在super之前
        super(val)
    }
}

子类可以继承父类的静态方法

class A {
  static sayA() {
    console.log('A');
  }
}

class Aa extends A {
}
B.sayA()  //A

Object.getPrototypeOf()

该方法可以用来判断子类的继承对象。

Object.getPrototypeOf(B)
/* 输出
class A {
  static hello() {
    console.log('hello world');
  }
}
*/
Object.getPrototypeOf(B)===A //true

super关键字

super有两种用法,一种是当作函数来使用,另外一种是当作对象来使用。

1、函数
super作为函数来调用时,代表了父类的构造函数。在前边提到了,子类必须要执行一次super函数。

class A {
    constructor(val){
        this.val=val
    }
}
class Aa extends A{
    constructor(val){
        super(val)
    }
}

在上面例子中,super()虽然代表了A的构造函数,但是返回的是子类Aa的实例,即super内部的this指向了Aa的实例。
这种情况下super相当于A.prototype.constructor.call(this),因此super只能用在子类的构造函数中。

2、对象
super作为对象时,在普通的方法中,指向了父类的原型对象,而在静态方法中,则是指向父类。

class A {
  sayA() {
    return 'A';
  }
}
class Aa extends A {
  constructor() {
    super();
    console.log(super.sayA()); // A
  }
}

子类Aa中的super.sayA()就将super当作一个对象。在普通方法中,指向了A.prototypesuper.sayA()也就相当于A.prototype.sayA(),因为super是指向父类的原型对象,所以在父类实例上的方法和属性(即在constructor中定义的)是无法通过super调用的。

class A {
    constructor(){
        this.val='A'
    }
}
class Aa extends A{
    constructor(){
        super()
    }
    sayA(){
        return super.val;
    }
}
var aa = new Aa('a')
console.log(aa.sayA()) //undefined

只有定义在父类的原型对象上(不在constructor中定义的),super就可以取到。

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

class A {
    constructor(){
        this.val='A'
    }
    sayA(){
        console.log(this.val)
    }
}
class Aa extends A{
    constructor(){
        super()
        this.val='a'
    }
    sayA(){
        super.sayA(); // 调用父类方法
        //相当于 super.sayA.call(this) this指向当前子类的实例
    }
}
var aa = new Aa()
console.log(aa.sayA()) // a 

虽然父类和子类都有val属性,但是在this是指向当前子类的实例,因此val='a'

相关标签: javascript