javascript 高级程序设计中有写,对象的继承总共有六种:
- 原型链继承,子原型是父原型的一个实例
- 借用构造函数继承,子构造函数调用父构造函数
- 组合式继承(组合 1 和 2)
- 原型式继承
- 寄生式继承
- 寄生式组合继承(组合 3 和 5)
原型链继承
1 | function Parent() { |
缺点是:由于子原型是父原型的一个实例,所以父级属性在子级的原型上,而不在每个子级的实例上,所以如果属性是引用类型时会互相影响。
借用构造函数继承
1 | function Parent() { |
解决了原型链继承中,属性没绑定到子实例里面的问题,但如果仅这样继承的话,父原型上的东西没有被继承
组合式继承
综合了以上两种继承方式,可以既继承原型,又把属性绑定到了子实例(从而覆盖原型的属性)
1 | function Parent() { |
缺点是:
- 父构造函数执行了两次
- 父实例上存储了多余的属性(压根用不到),浪费内存
原型式继承
创建一个临时的构造函数,并把这个临时的构造函数的 prototype 指向父原型
1 | function object(Parent) { |
相当于Object.create()
,ECMAScript 5 通过增加 Object.create()方法将原型式继承的概念规范化了。这个方法接收两个参数:作为新对象原型的对象,以及给新对象定义额外属性的对象(第二个可选)。在只有一个参数时,Object.create()与这里的 object()方法效果相同
寄生式继承
在原型式继承的基础上,做了一个封装:
1 | function createAnother(Parent) { |
寄生式组合继承
综合了寄生式继承和组合式继承,并克服了组合式继承的缺点
1 | function object(Parent) { |
ES6 的 class 语法糖,就是寄生式组合继承