前言
之前一直对原型链不太了解,所以继承也懵懵懂懂,最近终于对原型链有点心得了,抓紧弄懂继承!
原型链继承
核心:将父类的实例作为子类的原型
特点:
- 实例 是子类的 实例,也是父类的 实例
- 父类新增原型方法/原型属性,子类都能访问到
缺点:
- 父类一变,子类也变
- 无法实现多继承:一个子类只能继承一个父类,不能继承多个父类
- 子类新增属性/方法,必须在new () 后面执行
- 创建子类实例时,无法向父类构造函数传参
1 | function Parent(name) { |
构造继承
核心:在子类构造函数中利用 call/apply 把父类中通过 this 指定的属性/方法 复制到子类创建的实例中
特点:
- 实例不是父类的实例,只是子类的实例
- 创建子类实例时,可以向父类传递参数
- 可以实现多继承(call 多个父类对象)
缺点:
- 只能继承父类的实例方法/属性,不能继承父类原型上的方法/属性
- 每个子类都有父类实例对象的副本,影响性能
1 | function Parent (name) { |
组合继承(最常用)
核心:调用父类构造,继承父类的属性,保留传参的优点;将父类实例作为子类原型,实现父类原型 方法/属性 复用
特点:
- 结合了 原型链继承 与 构造继承 的优点
缺点:
- 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
1 | function Parent (name) { |
原型式继承
1 | const Parent = { |
寄生式继承
1 | const Parent = { |
寄生组合继承
核心:通过寄生方式,砍掉父类的实例属性。那么在调用两次父类的构造时,就不会初始化两次实例方法/熟悉,避免组合继承的缺点
优点:
- 非常完美
缺点:
- 实现较复杂
1 | function Parent(name) { |
ES6 - class中的super()实现
核心:调用super方法:创造父类的实例对象this,然后再用子类的构造函数修改this
1 | class Animal { |