# OOP:类型和继承

这里是 javascript 面向对象非常重要的部分。我们先讨论继承相关的问题,然后是再讨论类型

# 继承

类继承的目的是复用某些构造函数包括构造函数的原型,我们通过一个例子来讨论继承的几种实现方法。

先准备一个基类

// 原型链继承
const Animal = function() {
  this.name = ''
  this.sleep = function() {
    console.log(this.name + '正在睡觉!');
  }
}
Animal.prototype.eat = function() {
  console.log(this.name + '正在吃饭!');
}

# 1. 原型链继承

const Woman = function(){}
Woman.prototype = new Animal()
Woman.prototype.name = '女人'
Woman.prototype.buyBuyBuy = function(){
  console.log(this.name + ':去淘宝买买买...');
}

优点:

  • 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
  • 父类新增原型方法/原型属性,子类都能访问到
  • 简单,易于实现

缺点:

  • 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
  • 无法实现多继承
  • 来自原型对象的所有属性被所有实例共享
  • 创建子类实例时,无法向父类构造函数传参

# 2. 组合继承

通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

// 女人
const Woman = function(){
  Animal.call(this) // 调用父类构造函数
  this.name = '女人'
}
// 继承父类原型,必须要写到其他原型方法的前面
Woman.prototype = new Animal() 
// 修正构造函数
Woman.prototype.constructor = Woman 
Woman.prototype.buyBuyBuy = function(){
  console.log(this.name + ':去淘宝买买买...');
}

let w = new Woman()
console.log(w)
w.sleep()
w.eat()
w.buyBuyBuy()

优点

  • 可传参
  • 函数可复用
  • 可以实现多继承

缺点

  • 调用了两次父类构造函数

# 寄生组合式继承

// 女人
const Woman = function(){
  Animal.call(this)
  this.name = '女人'
}

function inherit(subType, superType) {
  var TempFn =  function() {
    this.constructor = subType
  }
  TempFn.prototype = superType.prototype
  subType.prototype = new TempFn();
}

inherit(Woman, Animal);

Woman.prototype.buyBuyBuy = function() {
  console.log(this.name + ':去淘宝买买买...');
}

let w = new Woman()
console.log(w)
w.sleep()
w.eat()
w.buyBuyBuy()

寄生组合式继承,是业内公认的最理想的继承方式。这种方式只调用了一次父类的构造函数,并且还能避免子类的原型链中出现多余的属性。

# 类型

写作中...

上次更新: 9/1/2020, 1:40:55 PM