年前最后一天班做一點干貨輸出吧,從class聊聊繼承

我們日常開發(fā)都會用到ES6, 比如我們擼React,寫組件肯定擼過class XX extends React.Component. constructor(){super(xx)}之類的。
今天就來看看這個class,我們知道JS里本身是沒有class這個概念,其他語言比如java,python是天生就有class的,JS肯定不服啊,所以在ES6里就引入了class,那么是class就真的是class嗎?No,此class非彼class,用的babel的同學肯定會知道,當我們打開編譯后的es6代碼,實際就是es5,里面并沒有class,還是prototype什么那些一堆亂七八糟的玩意兒,說白了,class只是一個語法糖,方便我們開發(fā)寫代碼而已。
好,那我們就來看看什么是真正的繼承吧。
Type 1: 原型鏈的方式可以實現(xiàn),talk is cheap, show me the code.亮代碼

  function Taylor () {
        this.name = 'Taylor'
        this.price = 7777
   }
  function Guitar () {
    this.dalao= '雨神'
  }

  Taylor.prototype = new Guitar()

  const guitar = new Taylor()

我想買一把吉他,吉他有很多品牌,比如泰勒馬丁雅馬哈各種,精挑細選最后看中了泰勒這個吉他品牌,就先定義一個子類叫泰勒,接著我們定義父類就是Guitar。
接下來就是關鍵的一步,Taylor.prototype = new Guitar(),將Guitar的實例賦給Taylor的顯式原型prototype,這樣就完成了最基本的原型鏈繼承。我們可以來試一下,再控制臺輸入以上代碼并執(zhí)行,然后
console.log(guitar.dalao)控制臺會輸出雨神大佬,在Taylor的定義里并沒有dalao的屬性,而現(xiàn)在我們卻可以輸出dalao這個屬性,就是通過原型鏈找到的,這就說明Taylor繼承了Guitar,也說明了雨神不僅是泰勒dalao,不管任何品牌吉他的都是dalao,是我等菜雞膜拜的大神。
好了,言歸正傳,這種原型鏈的方式也有缺點,比如如果父類的屬性是一個引用類型,在一個子類實例中修改了這個屬性之后新創(chuàng)建的子類實例也會被永久修改了。還有就是不能直接給父類構造函數(shù)傳參,因為會影響新建實例對象。

Type 2: 構造函數(shù)的方式可以實現(xiàn),talk is cheap, show me the code.亮代碼

 function Guitar (name) {
    this.dalao= name
    this.songs = []
  }
  function Taylor (dalao) {
    this.name = 'Taylor'
    this.price = 7777
    Guitar.call(this, dalao)
  }
  const guitar = new Taylor('雨神')

和上面一樣,我們改成構造函數(shù)的方式實現(xiàn)繼承,關鍵的一步,Guitar.call(this, '雨神'),改變了父類Guitar的執(zhí)行上下文this指向,讓this指向子類,換句話說就是把父類構造函數(shù)在子類構造函數(shù)里執(zhí)行一遍。而且解決了之前原型鏈繼承存在的問題,一個就是不能直接父類構造函數(shù)傳參,我們給Guitar定義了一個形參name,在new Taylor('雨神')里我們傳入雨神這個實參,然后我們和上面一樣在控制臺輸出console.log(guitar.dalao)控制臺也一樣會輸出雨神大佬,然后我們可以做下改動,Guitar.call(this, '小老弟60'),重復上面步驟,控制臺會輸出'小老弟60'.
第二個問題就是父類引用類型屬性,我這里放了了一個songs=[]一個空數(shù)組。然后我們給guitar實例的songs做加點東西。
guitar.songs.push('盜將行')我們年會表演的曲子,很好聽的,強烈推薦,沒聽過可以試試。然后我們新建一個Taylor的實例,const guitar222= new Taylor() console.log(guitar222.songs)
控制臺輸出一個[],發(fā)現(xiàn)之前我們的操作并沒有影響到后來新建的實例對象,這就解決了原型鏈的兩個缺點,當然構造函數(shù)模式 也有缺點,就是父類原型里定義的屬性子類是無法繼承的。
所以,我們取其精華去其糟粕,把二者合二為一,誕生了第三種繼承方式,組合繼承,就是把原型鏈和構造函數(shù)組合在一起實現(xiàn)繼承。
Type 3: 組合繼承的方式可以實現(xiàn),talk is cheap, show me the code.亮代碼

  function Guitar (name) {
    this.dalao= name
    this.songs = []
  }

  function Taylor (dalao) {
    this.name = 'Taylor'
    this.price = 7777
    Guitar.call(this, dalao)
  }
Guitar.prototype.band = 'HikWestlife'

Taylor.prototype = new Guitar()
Taylor.prototype.constructor = Taylor

const guitar = new Taylor('雨神')

這就是組合繼承,同時我們把Taylor.prototype.constructor的構造器指向Taylor。然而還是不夠完美,因為父類的構造函數(shù)執(zhí)行了兩次,為了更好的性能,我們發(fā)明了終極解放方案,寄生組合式繼承。

Type 4: 寄生繼承的方式可以實現(xiàn),talk is cheap, show me the code.亮代碼

  function Guitar (name) {
    this.dalao= name
    this.songs = []
  }

  function Taylor (dalao) {
    this.name = 'Taylor'
    this.price = 7777
    Guitar.call(this, dalao)
  }
Guitar.prototype.band = 'HikWestlife'

Taylor.prototype = Object.create(Guitar.prototype)
Taylor.prototype.constructor = Taylor

const guitar = new Taylor('雨神')

一起來試驗一下,我們在控制臺輸出console.log(guitar.band)發(fā)現(xiàn)會輸出"HikWestlife",一樣實現(xiàn)了組合繼承的功能,而且還只執(zhí)行了一次構造函數(shù)。
好了,這就是class的真面目,放假了。。過年~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • class的基本用法 概述 JavaScript語言的傳統(tǒng)方法是通過構造函數(shù),定義并生成新對象。下面是一個例子: ...
    呼呼哥閱讀 4,207評論 3 11
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,149評論 2 9
  • 基本語法 簡介 JavaScript語言中,生成實例對象的傳統(tǒng)方法是通過構造函數(shù). ES6提供更接近傳統(tǒng)語言的寫法...
    JarvanZ閱讀 941評論 0 0
  • 繼承6種套餐 參照紅皮書,JS繼承一共6種 1.原型鏈繼承 核心思想:子類的原型指向父類的一個實例 Son.pro...
    燈不梨喵閱讀 3,258評論 1 2
  • 我一直以來,為自己這份堅持感到不易!雖然每天記錄的就是一些瑣碎的事,但影響到了十歲的孩子,有時看著他那份堅持實在有...
    晴婕栩閱讀 223評論 0 0

友情鏈接更多精彩內容