继承

113 阅读1分钟

构造函数继承

在子类构造函数中使用 Parent.call(this)

缺点:不能继承父类的原型,所以不是真正的继承

Parent.prototype.family = "罗斯柴尔德家族"
function Parent() {
  this.name = "parent"
}
function Child() {
  Parent.call(this)
}
let child1 = new Child()
console.log(child1.name) // 输出 parent
console.log(child1.family) // 输出 undefined,拿不到父类原型上的方法

原型链继承

优点:可以继承父类的原型

缺点:父类引用值在子类实例实现了共用

Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
  this.name = "parent"
  this.arr2 = [11]
}
function Child() {
  this.name = "Child"
  this.arr3 = [111]
}
Child.prototype = new Parent()
let child1 = new Child()
let child2 = new Child()
console.log(child1.arr1) // [1]
console.log(child1.arr2) // [11]
console.log(child1.arr3) // [111]

child1.arr2.push(22)
console.log(child2.arr2) // [11, 22]

child1.family = "洛家"
console.log(child1.family) // "洛家"
console.log(child2.family) // "罗斯柴尔德家族"

构造函数 + 原型链 继承

优点:解决父类引用值共用问题

缺点:子类实例化的时候,父类构造函数被执行了两次

Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
  this.name = "parent"
  this.arr2 = [11]
}
function Child() {
  Parent.call(this)
  this.name = "Child"
  this.arr3 = [111]
}
Child.prototype = new Parent()
let child1 = new Child()
let child2 = new Child()
console.log(child1.arr1) // [1]
console.log(child1.arr2) // [11]
console.log(child1.arr3) // [111]

child1.arr2.push(22)
console.log(child2.arr2) // [11]

child1.family = "洛家"
console.log(child1.family) // "洛家"
console.log(child2.family) // "罗斯柴尔德家族"

构造函数 + 原型链 继承优化1

优点:子类实例化,父类被构造两次的问题

缺点:子类实例化后,构造函数变为Parent

Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
  this.name = "parent"
  this.arr2 = [11]
}
function Child() {
  Parent.call(this)
  this.name = "Child"
  this.arr3 = [111]
}
Child.prototype = Parent.prototype
let child1 = new Child()
console.log(child1.__proto__.constructor == Parent) // true

构造函数 + 原型链 继承优化2 完美继承

优点:完美继承

Parent.call(this)

Child.prototype = Object.prototype(Parent.prototype)

Child.prototype.constructor = Child

Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
  this.name = "parent"
  this.arr2 = [11]
}
function Child() {
  Parent.call(this)
  this.name = "Child"
  this.arr3 = [111]
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
let child1 = new Child()
console.log(child1.__proto__.constructor == Parent) // false
console.log(child1.__proto__.constructor == Child) // true

圣杯模式

var inherit = (function (){
    var F = function() {}
    return function(Target, Origin) {
      F.prototype = Origin.prototype
      Target.prototype = new F()
      Target.prototype.constructor = Target
      // uber表示对象的最终原型来自于谁
      Target.prototype.uber = Origin.prototype
    }
})()

ES6 class .. extends .. 继承