chenjianou / blog

我的个人博客
0 stars 0 forks source link

ES5实现继承 #27

Open chenjianou opened 3 years ago

chenjianou commented 3 years ago

构造函数继承

通过call改变this指向实现继承

function Parent (){
   this.name='xiaohua'
}
function Child (){
   Person.call(this)
   this.height = '180px'
}

new Child ()

这样的问题是我们虽然能拿到Parent的属性值但是无法拿到原型上的方法。对此我们引出第二种继承方式

原型继承

function Parent (){
   this.name='xiaohua'
}
function Child (){
   this.height = '180px'
}
Child.prototype = new Person

child = new Child ()

child2 = new Child2()

通过上面原型继承的方式我们可以得到该父类属性和方法。但是还有一个问题,当我们修改继承原型的属性时候,会影响到其他的子类。

组合继承(构造函数+原型)

function Parent (){
   this.name='xiaohua'
}
function Child (){
   Person.call(this)
   this.height = '180px'
}
Child.prototype = new Parent

child = new Child ()

通过这种方式可以解决,但是又多了一个问题,我们这里就多执行了一次Parent(Child.prototype = new Parent),

组合继承优化

function Parent (){
   this.name='xiaohua'
}
function Child (){
   Parent.call(this)
   this.height = '180px'
}
Child.prototype = Parent.prototype
child = new Child ()

Child的constructor指向出问题了

组合继承优化2(圣杯模式)

function Parent (){
   this.name='xiaohua'
}
function Child (){
   Parent.call(this)
   this.height = '180px'
}
 Child.prototype = Object.create(Parent.prototype); // es6方法Object.create
  Child.prototype.constructor = Child;

child = new Child ()

通过上面的案例我们可以自己实现一个继承方法inherit


//实现ES6 Object.create
function createObj  (o){
   let F = function (){}
  F.prototype = o
  return new o
}
// 父类
function SuperType(){
}

//子类
function Sub(){
   SuperType.call(this)
}

//继承
let inherit = function (target, origin){
   const prototype= createObj(origin.prototype)
   target.prototype = prototype
   target.prototype.constructor = target
   target.prototype.uber = origin
}

inherit(Sub, SuperType)

打完收工!!!

参考资料:https://juejin.cn/post/6844903872847151112