繼承

首先,定義一個父類

function Father (name) {
  this.name = name
  this.getName = function () {
    return this.name
  }
  this.setName = function (name) {
    this.name = name
  }
}

原型鏈繼承

function Son (name) {
  this.name = name
}
Son.prototype = new Father()

缺點:
沒有使用Father的構造函數,也即沒有復用Father的this.name=name
所有Son的實例共享一個Father實例,它的改變會影響到所有實例

構造函數繼承

function Son () {
  Father.apply(this, arguments)
}

缺點:
沒有繼承Father的原型
Father構造函數每次實例化都被調用

組合繼承

function Son () {
  Father.apply(this, arguments)
}
Son.prototype = new Father()

缺點:
仍然沒有解決Father構造函數多次調用問題

原型式繼承

/**
  @param {*} father 
*/
function inherit(father) {
  function Fn () {}
  Fn.prototype = father
  return new Fn()
}
var son = inherit(new Father())

原型式繼承也就是生成一個原型對象是給定對象的對象
對比:
解決了原型繼承共享的問題
缺點:
繼承的是Father實例不是原型
需要自行修改Son實例特定的屬性和方法

寄生式繼承

function inherit(father) {
  function Fn () {}
  Fn.prototype = father
  return new Fn()
}
// 寄生函數
function Son (father, name) {
  var son = inherit(father)
  son.name = name
  return son
}
var son = Son(new Father())

寄生式繼承就是先得到一個原型上“復制”Father的對象,然后在這個對象中添加新的需要的屬性,就像寄生在這個對象中一樣。
對比:
解決了自定屬性問題

寄生組合式繼承

function inherit(father) {
  function Fn () {}
  Fn.prototype = father
  return new Fn()
}
function Son () {
  Father.apply(this, arguments)
}
var tmp = inherit(Father.prototype)
Son.prototype = tmp
tmp.constructor = Son

寄生組合式繼承就是原型式繼承時繼承的是Father的原型而不是實例,這實現了原型繼承
同時,寄生函數使用調用Father構造函數的方式,復用構造函數

Object.create

var son = Object.create(new Father())

extends

class Son extends Father {}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。