JS继承方法总结
1.原型链继承
function SuperType() { |
存在的问题:
- 若原型中存在引用值, 则所有实例继承的都是同一引用对象。
- 子类实例化时不能给父类传参。
2.盗用构造函数
==解决的问题: 解决原型包含引用值导致的继承问题==
基本思路:在子类构造函数中通过call, apply调用父类的构造函数
function SubType() { |
优点:可以向父类构造函数传参
function SuperType(name){ |
缺点:必须在构造函数中定义方法,因此函数不能重用。(只继承了属性)
🍅🍅🍅3.组合继承
思路:使用原型链继承原型上的属性和方法,通过盗用构造函数继承实例属性。
缺点:存在效率问题。
解决办法:寄生式组合继承
最主要的效率问题是:父类的构造函数始终会被调用两次。
一次是在创建子类原型时, 一次是在子类构造函数中
function SuperType(name){ |
==组合继承弥补了原型链和盗用构造函数的不足,是 JavaScript 中使用最多的继承模式==。
而且组合继承也保留了 instanceof 操作符和 isPrototypeOf()方法识别合成对象的能力。
4.原型式继承
function object(o) { |
原型式继承非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合。
但要记住,属性中包含的引用值始终会在相关对象间共享,跟使用原型模式是一样的。
5.寄生式继承
寄生式继承背后的思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象
function createAnother(original){ |
寄生式继承同样适合主要关注对象,而不在乎类型和构造函数的场景。
object()函数不是寄生式继承所必需的,任何返回新对象的函数都可以在这里使用。
缺点:
- 通过寄生式继承给对象添加函数会导致函数难以重用,与构造函数模式类似。
6.寄生式组合继承
寄生式组合继承通过盗用构造函数继承属性,但使用混合式原型链继承方法。
基本思路:不通过调用父类构造函数给子类原型赋值,而是取得父类原型的一个副本。
说到底就是使用寄生式继承来继承父类原型,然后将返回的新对象赋值给子类原型
function inheritPrototype(subType, superType) { |
这个 inheritPrototype()函数实现了寄生式组合继承的核心逻辑。
这个函数接收两个参数:子类构造函数和父类构造函数。
在这个函数内部,第一步是创建父类原型的一个副本。然后,给返回的prototype 对象设置 constructor 属性,解决由于重写原型导致默认 constructor 丢失的问题。最后将新创建的对象赋值给子类型的原型。
instanceof 操作符和isPrototypeOf()方法正常有效。寄生式组合继承可以算是引用类型继承的最佳模式。
参考:
- JavaScript高级程序设计