总结一下红宝书中列出的6种JS继承方式

  • 原型链
function Super() {
this.fatherProperty = 1;
}

function Sub() {
this.sonProperty = 2;
}

Sub.prototype = new Super();

var newSon = new Sub();

核心:

子类的prototype是一个父类的实例

缺陷:

  1. 所有子类的prototype为同一个父类实例对象,如果该对象的某些属性是引用类型,那么通过修改一个子类实例的该属性,会影响所有的子类实例
  2. 在构造子类实例时无法向父类构造函数中传递参数
  • 构造函数
function Super() {
this.fatherProperty = 1;
}

function Sub() {
Super.call(this);
this.sonProperty = 2;
}

var newSon = new Sub();

核心:

在子类的构造函数上调用父类的构造函数,并将this绑定,使父类中的this和子类中的this在构造子类实例时都指向实例,这样实例继承的父类属性就直接在实例对象上面了

缺陷:

  1. 无法继承父类原型上的属性
  • 组合继承
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为子类本身

缺陷:

  1. 子类的构造函数中继承了父类的属性,所以子类实例上有一个父类的属性,__proto__上也存在父类的属性
  • 原型式继承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}

核心:

新对象的原型上有传入对象的所有属性

缺陷:

  1. 同原型链继承一样,包含引用的属性始终会被共享,“一改万变”
  2. 不是类继承
  • 寄生式继承
function createAnother(o){
var clone = object(o)
clone.sayHi = function(){
alert('hi')
}
return clone
}

核心:

使用工厂模式封装了原型式继承过程

缺陷:

  1. 函数复用性低
  2. 不是类继承
  • 寄生组合式继承
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;
}

核心:

结合了组合继承和寄生继承,没有创建父类实例的步骤,取而代之的是直接拷贝一份父类原型的副本,这样不会执行两次父类的构造函数

缺陷:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注