不使用class的六种继承实现方式总结
原型链 | 假借构造函数 | 组合继承 | 原型式(Prototypal) | 寄生式 | 组合寄生式 | |
主要形式 | subType.prototype = new SuperType() | SuperType.call(this) | subType.prototype = new SuperType() + SuperType.call(this) | object(o)返回以o为原型的对象 | object(o)然后添加新属性和方法,封装在一个函数中,直接返回新的对象 |
inheritPrototype(SubType, SuperType) + SuperType.call(this)
|
继承原型属性及方法 | ✅ | ✅ |
✅ |
✅ (原型已经是个具体的对象) |
✅ | |
可通过构造函数传参改变继承来的属性值 | ✅ | ✅ | 不涉及构造函数 | 不涉及构造函数 | ✅ | |
实例间共享原型属性(实现函数复用) | ✅ | ✅ | ✅ | ✅ | ✅ | |
实例间不用共享引用类型的实例属性 | ✅ | ✅ | ✅ | |||
形成原型链 (instanceof, isPrototypeOf判断为真) |
✅ | ✅ | ✅ | ✅ | ✅ | |
子类原型上没有多余的父类实例属性 | ✅ (继承的所有属性都在原型上) |
✅ (继承的所有属性都在实例上) |
调用了两次SuperType构造函数,子类原型上和实例上个有一套父类实例属性 | 对象之间的继承,不分实例/原型 | 对象之间的继承,不分实例/原型 | ✅ |
其他 | 继承时将父类的实例属性变成了子类原型属性 |
注意:
对于所有共享原型属性的继承方法,当改变原型中非引用类型的属性的值时,实际发生的是在实例上新增了一个同名的实例属性,因此改变一个实例的非引用类型属性的值,不会影响到其他实例。