前端 father::类的继承

方式

寄生+构造函数(最成熟⭐)(也叫寄生组合继承)

  • 结合借用构造函数传递参数和寄生模式实现继承
  • 使用真正的prototype(原型对象), 原型继承方法, 构造函数构造属性
// 该过程可以被称为寄生
function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype); // 创建subType的原型对象,并把其__proto__属性指向父类的原型对象
  prototype.constructor = subType;                    // 把新建的原型对象中constructor 属性正确指向子类构造函数
  subType.prototype = prototype;                      // 指定对象,将新创建的对象赋值给子类的原型
}
 
// 父类初始化实例属性和原型属性
function SuperType(name){
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
  alert(this.name);
};
 
// 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
function SubType(name, age){
  SuperType.call(this, name); 
  this.age = age;
}
 
// 将子类原型与父类的原型链接起来
inheritPrototype(SubType, SuperType);
 
// 新增子类原型属性
SubType.prototype.sayAge = function(){
  alert(this.age);
}
 
var instance1 = new SubType("xyc", 23);
var instance2 = new SubType("lxy", 23);
 
instance1.colors.push("2"); // ["red", "blue", "green", "2"]
instance1.colors.push("3"); // ["red", "blue", "green", "3"]

这是最成熟的方法,也是现在库实现的方法

不成熟的方式

  • 原型链继承:将父类的实例作为子类的prototype(原型对象),通过 prototype 进行继承
    • 多个子类实例共用一个父类实例,导致互相污染属性
  • 构造继承:通过重新调用父类的构造函数,将父类的实例属性复制给子类
  • 组合继承:就是 原型链继承 和 构造继承,一起使用
    • 缺点:父类的属性同时存在于子类实例和子类原型对象中,造成冗余
  • 寄生继承:浅拷贝父类实例成一个副本对象,给这个副本对象添加一些子类的属性或方法,把这个副本作为子类的实例
    • 缺点:因为浅拷贝,所以多个子类实例共用相同的属性值,导致会造成互相污染