class继承

114 阅读1分钟

ES5 / ES6继承的区别:

  • ES5: 先创建子类的实例对象this,再添加父类的属性和方法到子类的this上;
  • ES6:先将父类实例对象的属性和方法添加到this上(此时需要用到super),然后再用子类的构造函数修改this;

1.基本继承语法:

class Aclass {
    say() {
        console.log('Aclass');
    }
}
class Bclass extends Aclass {};

var c = new Bclass();
c.say(); // 'Aclass'

2.super:表示父类的构造函数,用来新建父类的this对象;

情况1: 在子类显示定义constructor时,需要调用super,否则会在实例的时候报错;

/*
   为何报错?步骤如下:
    1.子类的this对象先通过父类的构造函数完成塑造;
    2.得到父类属性和方法后,再绑定自己的属性和方法;
   如果不使用super,则无法塑造this;
*/ 

class Aclass {}
class Bclass extends Aclass {
    constructor() {
        super(); // 这里不调用super,实例的时候会报错;
    }
}
var c = new Bclass();

情况2: 不显示定义constructor时子类继承可以不调用super方法,因为会被默认添加;

class Aclass {
    say() {
        console.log('Aclass')
    }
}
class Bclass extends Aclass {
    sayB() {
        super.say();
    }
}
var c = new Bclass();
c.sayB(); // 'Aclass'

情况3: 子类constructor的this必须在super之后才能使用,否则在事例的时候报错;

class Aclass {}
class Bclass extends Aclass {
    constructor(x) {
        this.x = x; // ReferenceError
        super()
        this.x = x; // 正常使用;
    }
}
var c = new Bclass();

情况4: super作为对象调用时,super方法内部的this指向当前子类;

class Aclass {
    x = 'A';
    constructor() {
        this.x = 'C'
    }
    say() {
        console.log(`say ${this.x}`)
    }
}
class Bclass extends Aclass {
    constructor() {
        super()
        this.x = 'B';
    }
    sayB() {
        super.say();
    }
}

var c = new Bclass();
c.sayB(); // 'say B';

3.类的prototype和__proto__属性: 和ES5一样;

  • __proto__: 表示构造函数的继承,指向父类;
  • prototype: 表示方法的继承,总是指向父类的prototype属性;
class Aclass {
}
class Bclass extends Aclass {
}

Bclass.__proto__ === Aclass; // true
Bclass.prototype.__proto__ === Aclass.prototype; // true