总结一下红宝书中列出的6种JS继承方式
- 原型链
function Super() {
this.fatherProperty = 1;
}
function Sub() {
this.sonProperty = 2;
}
Sub.prototype = new Super();
var newSon = new Sub();
核心:
子类的prototype是一个父类的实例
缺陷:
- 所有子类的prototype为同一个父类实例对象,如果该对象的某些属性是引用类型,那么通过修改一个子类实例的该属性,会影响所有的子类实例
- 在构造子类实例时无法向父类构造函数中传递参数
- 构造函数
function Super() {
this.fatherProperty = 1;
}
function Sub() {
Super.call(this);
this.sonProperty = 2;
}
var newSon = new Sub();
核心:
在子类的构造函数上调用父类的构造函数,并将this绑定,使父类中的this和子类中的this在构造子类实例时都指向实例,这样实例继承的父类属性就直接在实例对象上面了
缺陷:
- 无法继承父类原型上的属性
- 组合继承
function Super() {
this.fatherProperty = 1;
}
function Sub() {
Super.call(this);
this.sonProperty = 2;
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub
var newSon = new Sub();
核心:
原型链+构造函数的伪经典继承,结合两者优势,通过构造函数继承实例属性,原型链继承原型属性,并且让子类原型的constructor为子类本身
缺陷:
- 子类的构造函数中继承了父类的属性,所以子类实例上有一个父类的属性,__proto__上也存在父类的属性
- 原型式继承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
核心:
新对象的原型上有传入对象的所有属性
缺陷:
- 同原型链继承一样,包含引用的属性始终会被共享,“一改万变”
- 不是类继承
- 寄生式继承
function createAnother(o){
var clone = object(o)
clone.sayHi = function(){
alert('hi')
}
return clone
}
核心:
使用工厂模式封装了原型式继承过程
缺陷:
- 函数复用性低
- 不是类继承
- 寄生组合式继承
function Super() {
this.fatherProperty = 1;
}
function Sub() {
Super.call(this);
this.sonProperty = 2;
}
inheritPrototype (Sub, Super)
var newSon = new Sub();
function inheritPrototype (subType, superType) {
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
核心:
结合了组合继承和寄生继承,没有创建父类实例的步骤,取而代之的是直接拷贝一份父类原型的副本,这样不会执行两次父类的构造函数
缺陷:
- 无