原型链实现继承
- 核心: 子类原型等于父类的实例, 修改了原型对象
- 缺点: 多个实例对象操作引用类型数据, 数据会被覆盖
- 原理: 修改了实例对象的原型对象, 改变了原型链的指向
function Person () {
this.args = ['red', 'yellow']
this.name = 'parent'
}
function Child () {
this.name = 'child'
}
Child.prototype = new Person()
Child.prototype.constructor = Child
const child = new Child()
构造函数实现继承
- 核心: 使用 call 方法, 显示的改变父类的 this 指向子类
- 缺点: 只能继承父类实例身上的属性和方法, 并且每一个子类身上都这些属性和方法的副本, 影响性能
- 原理: 显示的让父类的 this 指向子类
function Person () {
this.colors = ['blue', 'pink']
this.name = 'parent'
}
Person.prototype.get = function () {
console.log(this)
}
function Child () {
Person.call(this)
this.name = 'child'
}
const child = new Child()
组合式实现继承
- 核心: 修改原型链的指向, 父类实例属性和方法绑定给子类
- 缺点: 对象身上有父类的实例属性和方法, 同时原型身上也绑定了一份属性和方法
- 原理: 修改原型链指向, 将父类实例属性和方法绑定给子类, 这样每次调用会先获取实例对象身上的属性, 如果没有再找原型链身上的方法,
function Person () {
this.colors = ['bule', 'pink']
this.name = 'parent'
}
Person.prototype.get = function () {
console.log(this)
}
function Child () {
Person.call(this)
this.name = 'child'
}
Child.prototype = new Person()
Child.prototype.constructor = Child
const child = new Child()
原型式实现继承
- 核心: 使用 Object.create() 方法, 以一个对象为原型, 继承这个对象身上的方法
- 缺点: 多个实例对引用类型数据进行操作, 会导致数据覆盖, 同时他无法传递参数
- 原理: 使用 Object.create() 方法, 以一个对象作为对象原型继承
const obj = {
colors: ['blue', 'white'],
name: 'parent'
}
const instance = Object.create(obj)
寄生实现继承
- 核心: 在原型式继承的基础上,增强对象, 返回增强对象
- 缺点: 和原型式继承一致, 如果多个实例对引用类型进行操作,会覆盖数据, 也无法传递参数
- 原理: 在原型式继承的基础上, 增强对象
function strongObj(obj){
const temp = Object.create(obj)
temp.get = function () {
console.log(this)
}
return temp
}
const obj = {
colors: ['white', 'black'],
name: 'parent'
}
const instance = strongObj(obj)
组合寄生实现继承 (成熟的方法, 库也在使用)
- 核心: 原型链继承 + 构造函数继承 + 寄生式继承
- 缺点: 实现复杂, 对新手不友好, 原型链有污染的风险, 如果修改过父类,那么整个原型链都会被污染, 有性能消耗, 依然存在, 拷贝以及修改原型等操作
- 原理: 修改原型链的指向, 在实例身上添加属性, 在原型式寄生的基础上增强对象
function strongObj (Child, Parent) {
const prototype = Object.create(Parent.prototype)
prototype.constructor = Child
Child.prototype = prototype
}
function Person () {
this.colors = ['bule', 'pink']
this.name = 'parent'
}
Person.prototype.sayHi = function () {
console.log(this)
}
function Child () {
Person.call(this)
this.name = 'child'
}
strongObj(Child, Person)
const instance = new Child()
混入式实现继承
- 核心: 使用 Object.assign 方法,复制多个对象原型上的方法和属性到目标对象身上
- 缺点: 代码可读性差, 原型链容易造成污染,在合并时, 如果出现同名的方法和属性, 后面的会覆盖前面的
- 原理: 使用 Object.assign 方法复制原型对象身上的方法, 主要是拷贝原型上的属性和方法
function Parent () {
this.colors = ['blue', 'pink']
this.name = 'parent'
}
Parent.prototype.sayHi = function () {
console.log('hi')
}
function Child () {
this.name = 'child'
}
Child.prototype.sayHello = function () {
console.log('hello')
}
function Son () {
Parent.call(this)
Child.call(this)
}
const prototype = Object.create(Parent.prototype)
Object.assign(prototype, Child.prototype)
Son.prototype = prototype
Son.prototype.constructor = Son
const instance = new Son()
Es6 class extends 继承
- 核心: 使用 es6 提供的关键字 extends 以及 super 关键字 实现继承,
- 缺点: 和寄生组合式一致, 他的内部实现就是这种方式
- 原理: 使用寄生组合式进行实现
class ParentClass {
colors: ['pink']
constructor (name) {
this.name = name
}
sayHi () {
console.log('hi')
}
}
class ChildClass extends ParentClass {
colors: ['blue']
constructor (name) {
super(name)
}
}
const instance = new ChildClass('ldh')