面向对象之继承理解
较为常用的继承有原型链继承、借用构造函数、组合式继承、寄生组合式继承,以及ES6继承,其他的还有原型式继承、寄生式继承
原型链继承
- js以原型链作为实现继承的主要方法
- 基本思想是利用原型链让一个引用类型继承另一个引用类型的属性和方法
- 构造函数、原型、实例的关系
- 每个构造函数都有一个原型对象
- 原型对象都有一个指向构造函数的方法
- 实例都包含一个指向原型对象的一个指针
|
|
只要是原型链中出现过的原型,都可以说是该原型链派生的实例的原型。
缺点:
- 子类型无法给超类型传递参数,在面向对象的继承中,我们总希望通过 var child = new Child(‘son’, ‘father’); 让子类去调用父类的构造器来完成继承。而不是通过像这样 new Parent(‘father’) 去调用父类。
- Child.prototype.sayName 必须写在 Child.prototype = new Parent(‘father’); 之后,不然就会被覆盖掉。
借用构造函数 (类式继承)
- 在子类型构造函数的内部调用超类型构造函数,通过call,apply 改变对象的this指向
|
|
相当于 Parent 这个函数在 Child 函数中执行了一遍,并且将所有与 this 绑定的变量都切换到了 Child 上,这样就克服了第一种方式带来的问题。
缺点:
- 没有原型,每次创建一个 Child 实例对象时候都需要执行一遍 Parent 函数,无法复用一些公用函数。
组合式继承(原型+构造函数继承)
|
|
缺点:
- 组合式继承是 JS 最常用的继承模式,但组合继承使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部。
原型式继承
- 基于一个对象上,这个对象相当于作为原型,再根据需求对得到的对象加以修改
- 在没有必要兴师动众创建构造函数,而只想让一个对象与另一个对象保持类似的情况下使用
|
|
寄生式继承
- 创建一个仅用于封装继承过程的函数,在函数内部以某种方式增强对象
|
|
寄生组合式继承
- 组合继承最大的问题是无论什么情况下都会调用两次超类型构造函数
- 一次是创建子类型原型时,一次是子函数的内部构造函数
- 寄生组合继承通过借用构造函数来继承属性,通过原型链混成形式来继承方法。
- 思路是不必为了指定的子类型原型而调用超类型的构造函数。
- 使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型
|
|
- 寄生组合式继承方式,跟组合式继承的区别在于,不需要在一次实例中调用两次父类的构造函数
- 假如说父类的构造器代码很多,还需要调用两次的话对系统肯定会有影响,寄生组合式继承的思想在于:用一个 F 空的构造函数去取代执行了 Parent 这个构造函数。
ES 6 继承
- ES6提供了更接近传统语言”类”的写法,引入了Class(类)这个概念,作为对象的模板。
- 通过class关键字,可以定义类。
- 基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到。
- 新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。下面我们用ES6的语法实现类的继承。
|
|
如果项目中使用到ES6语法开发,推荐使用ES6继承
参考文献
30 分钟学会 JS 继承
读书笔记–对象、实例、原型、继承
javascript高级程序设计
推荐文章
vue2.x Cnode社区
基于vue1.0开发的移动端H5积分商城项目
使用gulp前端自动化构建工具搭建前端项目
觉得有用的话,记得在GitHub中给个star哦!