JavaScript內(nèi)的繼承
●?在 JavaScript 內(nèi), 繼承是面向?qū)ο笞兂芍幸粋€(gè)重要的開發(fā)思想, 核心就是讓 A 對(duì)象使用 B 對(duì)象的屬性和方法. 說白了, 就是為了資源整合, 讓我們的代碼復(fù)用性更高, 后期的可維護(hù)性和可擴(kuò)展性也更高.
●?在 JS 中, 每一個(gè)對(duì)象都有一個(gè)自己的原型對(duì)象, JS 內(nèi)的繼承就是依賴這個(gè)原型對(duì)象, 而且原型對(duì)象也有自己的原型對(duì)象, 就是這一個(gè)一個(gè)的原型對(duì)象組成了原型鏈, 這就是繼承的核心.
●?舉個(gè)例子 :
○?有一位老父親, 努力了半輩子, 蓋了一個(gè)大房子

○?這個(gè)時(shí)候, 不管這個(gè)老父親有多少個(gè)兒子, 他的兒子都是可以住在這個(gè)房子里面的
○?可以用這個(gè)房子所有內(nèi)容

○?但是如果要是沒有繼承的話, 那么他的每一個(gè)兒子都要自己去從新蓋房子
●?這就是我們繼承的意義, 接下來我們就詳細(xì)的說一說 JavaScript 內(nèi)常見的繼承方案
回顧之前的知識(shí)點(diǎn)
原型
●?構(gòu)造函數(shù)(類) 有一個(gè)自己的屬性 prototype, 是一個(gè)對(duì)象
●?每一個(gè)對(duì)象都有一個(gè)自己的屬性 __proto__, 指向所屬構(gòu)造函數(shù)的 prototype
●?這樣, 就將構(gòu)造函數(shù)和對(duì)象連接了起來

原型鏈
●?原型鏈就是 __proto__ 串聯(lián)起來的對(duì)象鏈狀結(jié)構(gòu)
●?每一個(gè)對(duì)象都會(huì)有自己的原型對(duì)象( __proto__ )

原型鏈訪問規(guī)則
●?對(duì)象成員的訪問規(guī)則就是按照原型鏈的機(jī)制進(jìn)行訪問的
●?當(dāng)你訪問一個(gè)對(duì)象的成員的時(shí)候
○?會(huì)首先在對(duì)象自己內(nèi)查找
○?如果自己有, 直接使用自己的
○?如果自己沒有, 就會(huì)自動(dòng)去到自己的 __proto__ 查找
○?如果還沒有, 在繼續(xù)去 __proto__ 查找
○?以此類推
○?直到 Object.prototype 都沒有, 那么返回 null
常見繼承方案
1.? 原型鏈繼承
●?本質(zhì)就是在原型鏈上做一些手腳, 讓某一個(gè)對(duì)象的 __proto__ 能指向另一個(gè)對(duì)象就好了
●?核心 : 子類的原型指向父類的實(shí)例
●?缺點(diǎn) :
○?子類沒有自己的原型, 因?yàn)樽宇惖脑途褪歉割惖膶?shí)例
○?在繼承屬性這方面, 所有子類實(shí)例對(duì)象繼承下來的屬性都是一模一樣的
●?優(yōu)點(diǎn) :
○?屬性和方法都能繼承下來
2.? 借用構(gòu)造函數(shù)繼承
●?本質(zhì)就是把父類構(gòu)造函數(shù)當(dāng)做一個(gè)普通函數(shù)來使用, 在利用一些改變 this 指向的方法
●?核心 : 利用 call 或者 apply 方法調(diào)用父類構(gòu)造函數(shù), 讓其 this 指向子類的實(shí)例
●?缺點(diǎn) :
○?只能繼承父類的屬性, 原型上的方法不能繼承
●?優(yōu)點(diǎn) :
○?子類有自己的原型, 可以向自己的原型上添加專屬于子類的內(nèi)容
○?對(duì)于繼承的屬性而言, 每一個(gè)子類的實(shí)例都會(huì)繼承一套自己的屬性
3.? 基礎(chǔ)組合繼承
●?本質(zhì)就是把上面的 原型繼承 和 借用構(gòu)造函數(shù)繼承 組合在一起使用而已
●?將以上兩種繼承方式的優(yōu)點(diǎn)全部合并在一起, 號(hào)稱最早的完美繼承
4.? 寄生繼承
●?本質(zhì)就是是利用一個(gè)空對(duì)象來包裝父類的實(shí)例對(duì)象,然后再將該空對(duì)象的原型設(shè)置為父類的原型對(duì)象,最后將該空對(duì)象返回作為子類的實(shí)例對(duì)象,從而實(shí)現(xiàn)繼承。
5.? 寄生組合繼承
●?這是一個(gè)非常經(jīng)典的繼承方案, 他是結(jié)合了 寄生繼承 和 基礎(chǔ)組合繼承 兩者創(chuàng)造出來的. 并且解決了組合繼承中重復(fù)調(diào)用構(gòu)造函數(shù)的尷尬, 同時(shí)也很好的避免了寄生繼承中的原型鏈污染, 是我個(gè)人覺得非常優(yōu)秀得以中繼承方案, 不知道是哪一個(gè)大神想出來的方案.
●?在寄生組合繼承中,我們首先使用組合繼承的方式創(chuàng)建對(duì)象和原型之間的關(guān)系,然后通過寄生繼承的方式修正原型上不需要的屬性

6.? ES6 的類繼承語法
●?在 ES6 規(guī)范中, 出現(xiàn)了類繼承的語法
●?也就是說, 我們可以不需要以上這些亂七八糟的玩意了, 直接上語法

●?我們可以直接使用 extends 關(guān)鍵字進(jìn)行父類的繼承
○?注意 : 還需要在類的構(gòu)造器內(nèi)寫一個(gè) super 來繼承父類屬性