借用(构造函数)继承
- 构造继承特点:
- 子类实例共享父类引用属性的问题
- 创建子类实例时,可以向父类传递参数 s
- 可以实现多继承(call 或 apply 多个父类对象)
- 构造继承缺点:
- 实例并不是父类的实例,只是子类的实例
- 只能继承父类的实例属性和方法,不能继承原型属性和方法
- 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
原型继承
原型的特点:共享一个空间!!!!
原型及原型链:
- 所有的函数都有一个属性prototype,这个属性可以找到该函数后面对应的原型对象。
- 所有的对象都有一个属性
__proto__
,通过这个属性可以找到该对象后面对应的原型对象,原型对象通过__proto__
这个属性可以找到当前原型对象的父级原型对象,一直找到顶级原型Object.prototype,再找,则找到null,这个过程称为原型链 - 所有原型对象都有一个属性constructor,通过这个属性可以找到当前原型对象对应的构造函数。
特点:
- 非常纯粹的继承关系,实例是子类的实例,也 是父类的实例
- 父类新增原型方法/原型属性,子类都能访问到
- 简单,易于实现
缺点:
要想为子类新增原型属性和方法,必须要在new 父类()这样的语句之后执行。要想为子类新增实例属性和方法,必须要在构造函数中添加
无法实现多继承
来自原型对象的所有属性被所有实例共享
组合继承
- 特点:
- 可以继承实例属性和方法,也可以继承原型属性和方法
- 既是子类的实例,也是父类的实例
- 不存在引用属性的共享问题
- 可传参
- 函数可复用
- 缺点:
- 调用了两次父类构造函数,生成了两份实例
ES6 的继承语法
class 子类名 extends 父类名{
//1.通过extends指定继承于那个父类
constructor([参数]){
//调用父类的构造函数
super([参数]);
}
}