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