# 继承(委托)

继承(相当于现实世界继承财务,把父亲的积累的财富,给自己使用)(可以写一篇文章了)

# 原型链继承

原型链天然向上寻找不存在与自己的属性

function Father(name = 'father') {
  this.name = name
  this.garage = ['BMW', 'Benz']
  this.wealth = 10000000
}

function Son() {}
Son.prototype = new Father()
Son.prototype.constructor = Son
const son = new Son()
son.wealth

问题:

  1. 子类无法传参(无法拥有自己的姓名)
  2. 父类的属性是引用类型,会和子类一同修改(共用同一个车库)

借用构造函数解决上面问题

# 借用构造函数继承 经典继承

call 能够改变 this 的指向 ,所以我们将子类型构造函数的内部调用超类型构造函数

function Father(name = 'father') {
  this.name = name
  this.garage = ['BMW', 'Benz']
  this.wealth = 10000000
}
function Son(name) {
  Father.call(this, name) //继承了Father,且向父类型传递参数
}
var son1 = new Son('son1')
son1.garage.push('Land Rover')
console.log(son1)
var son2 = new Son('son2')
son2.garage.push('Land')
console.log(son2)

问题:

  1. 无法继承之后父类购买的豪宅了 (Father.prototype.house = []无法在子类继承)

# 组合继承

function Father(name = 'father') {
  this.name = name
  this.garage = ['BMW', 'Benz']
  this.wealth = 10000000
}

function Son(name) {
  Father.call(this, name)
}

// 原型链关联

Son.prototype = new Father()
Son.prototype.constructor = Son

const son = new Son('son') // 解决传参

Father.prototype.getMoney = function () {
  this.wealth++
} // 解决继承(能力增强)

console.log(son.getMoney)

问题:

  1. 父类的构造函数被调用了两次
  2. 子类原型上会存在父类实例属性,浪费内存

# 原型式继承

借助原型可以基于已有的对象创建新对象, 同时还不必因此创建自定义类型

//具体的一个示例
const bier = {
  name: 'bier',
  wealth: 10000000,
  garage: ['法拉利', '劳斯莱斯'],
}

function object(obj) {
  function F() {}
  F.prototype = obj
  return new F()
}

const son = object(bier) // 在 ECMAScript5 中,通过新增 object.create() 方法规范化了上面的原型式继承.
const son1 = Object.create(bier)
// son son1 bier公用同一个车库

问题:

  1. 和原型链继承存在一样的问题

# 寄生式继承

寄生式继承的思路与(寄生)构造函数和工厂模式类似, 即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象. 如下.

const father = {
  name: 'bier',
  wealth: 10000000,
  garage: ['法拉利', '劳斯莱斯'],
}

function createSon1(original) {
  var clone = Object.create(original) //通过调用object函数创建一个新对象
  clone.sayHi = function () {
    //以某种方式来增强这个对象
    alert('hi my name is son1')
  }
  return clone //返回这个对象
}
console.log(createSon1(father))
function createSon2(original) {
  var clone = Object.create(original) //通过调用object函数创建一个新对象
  clone.sayHi = function () {
    //以某种方式来增强这个对象
    alert('hi my name is son2')
  }
  clone.name = 'son2'
  return clone //返回这个对象
}

console.log(createSon2(father))

问题:

  1. 每个不同的增强示例都需要一个创建函数

# 寄生组合继承

又要解决增强问题,又要解决不用调用第二次父类构造函数(增强子类原型) 。不必为了指定子类型的原型而调用超类型的构造函数

Object.create(Parent.prototype)

function Father(name = 'father') {
  this.name = name
  this.garage = ['BMW', 'Benz']
  this.wealth = 10000000
}

function Son(name) {
  Father.call(this, name)
}

// 原型链关联

Son.prototype = Object.create(Father.prototype)
Son.prototype.constructor = Son
Father.prototype.getMoney = function () {
  this.wealth++
}
const son = new Son(1)