原型继承
构造函数、原型和实例之间的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个原型对象的指针。
继承的本质就是复制,即重写原型对象,代之以一个新类型的实例。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function SubType() {
this.subproperty = false;
}
// 这里是关键,创建SuperType的实例,并将该实例赋值给SubType.prototype
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
}
var instance = new SubType();
console.log(instance.getSuperValue()); // true
但原型链方案存在缺点:多个实例对引用类型的操作会被篡改。
Class继承
ES6类extends实现继承
class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
// extends表示继承自哪个类
class Child extends Parent {
constructor(value) {
// super调用父类的构造函数
super(value)
this.val = value
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
class实现继承的实质上是先创建父类的实例对象this,然后再用子类的构造函数修改this。因为子类没有自己的this对象,所以必须先调用父类的super()方法。