摘要:實際上也就是在原型鏈繼承的代碼中添加在子類的構造函數中調用父類構造函數。寄生組合式繼承在指定子類的原型的時候不必調用父類的構造函數,而是直接使用創建父類原型的副本。
原本地址:http://www.ahonn.me/2017/01/2...
眾所周知,JavaScript 的繼承是實現繼承,而沒有 Java 中的接口繼承。這是因為 JavaScript 中函數沒有簽名,而實現繼承依靠的是原型鏈來實現的。
原型鏈繼承JavaScript 中通過修改對象原型指向的對象來實現繼承,即是將一個對象的原型指向要繼承的對象實例,從而實現繼承對象的屬性及方法。
function SuperType() { this.type = "super"; } SuperType.prototype.getType() { return this.type; } function SubType() { this.type = "sub"; } SubType.prototype = new SuperType(); var sub = new SubType(); console.log(sub.getType()); // "sub"原型鏈繼承的不足
實際上,上面的代碼還缺少一句代碼,我們將 SubType 的原型指向了 SuperType 的實例,即SubType.prototype.constructor 會返回 SuperType 而不是 SubType,使用 instanceof 操作符返回的將是 SuperType。所以需要將 SubType.prototype.constructor 重新指向 SubType。
// ... SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; // ...
但即使是這樣,原型鏈繼承依然有兩點問題:原型中的實例引用類型屬性會在所有對象實例中共享,無法想 Java 的繼承一樣向父類的構造函數中傳遞參數。
其他繼承方式由于原型鏈繼承存在一些不足,為了解決這些不足,JavaScript 中還有其他的幾種繼承的方式。
借用構造函數因為原型鏈無法傳遞參數到父類的構造函數中,因此出現了這種叫做借用構造函數的技術。顧名思義,即是借用父類的構造函數在子類中進行調用。
function SuperType() { // ... } function SubType() { SuperType.call(this); // <- 執行父類構造函數 // ... }
借用構造函數雖然解決了構造函數傳參的問題,但是當父類擁有方法時每個子類的實例都會擁有獨立的方法,這個問題與多帶帶使用構造函數模式定義類型的時候相同。
組合繼承類比使用構造函數模式定義類型時的解決方法(組合構造函數模式與原型模式),繼承時的解決方法也類似。即組合原型鏈繼承和借用構造函數,屬性由借用構造函數的方式繼承,方法由原型鏈繼承。
實際上也就是在原型鏈繼承的代碼中添加在子類的構造函數中調用父類構造函數。
function SuperType() { this.type = "super"; } SuperType.prototype.getType() { return this.type; } function SubType() { SuperType.call(this); this.type = "sub"; } SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType;寄生組合式繼承
組合繼承是常用的繼承方式,但是同樣的也是有不足之處:調用了兩次父類的構造函數,一次在子類構造函數中調用父類構造函數,一次在實例父類對象賦值給子類的原型。
寄生組合式繼承在指定子類的原型的時候不必調用父類的構造函數,而是直接使用 Object.create() 創建父類原型的副本。
function SuperType() { // ... } function SubType() { SuperType.call(this); // ... } SubType.prototype = Object.create(SuperType.prototype); // 直接使用父類原型創建副本 SubType.prototype.constructor = SubType;ES6 中的繼承
ES6 引入了 class 關鍵子,可以像其他語言中一樣使用 extends 關鍵字來繼承。雖然能夠使用 extends 實現繼承,但實際上內部還是基于原型。
class SubType extends SuperType { constructor() { super(); // ... } // ... }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81364.html
摘要:委托上面的代碼結合了構造函數和原型兩種方式去創建對象,首先聊聊構造函數構造函數構造函數本質上還是函數,只不過為了區分將其首字母大寫了而已。注意注釋掉的代碼是自動執行的,但這并不是構造函數獨有的,每個函數在聲明時都會自動生成。 首先看看下面兩個1+1=2的問題: 問題一:為什么改變length的值,數組的內容會變化? var arr = [1]; arr.length = 3; aler...
摘要:前言面試中對于技術職位,一般分筆試與面談,如果面試官的一些小問題你可以立馬找到對應的知識點擴展開來,那么這就是你的優勢,本系列將講述一些面試中的事,不會很詳細,但是應該比較全面吧。 前言 面試中對于技術職位,一般分筆試與面談,如果面試官的一些小問題你可以立馬找到對應的知識點擴展開來,那么這就是你的優勢,本系列將講述一些java面試中的事,不會很詳細,但是應該比較全面吧。 主要內容 pa...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
閱讀 1672·2021-11-23 09:51
閱讀 2688·2021-11-22 09:34
閱讀 1322·2021-10-14 09:43
閱讀 3665·2021-09-08 09:36
閱讀 3212·2019-08-30 12:57
閱讀 2031·2019-08-30 12:44
閱讀 2522·2019-08-29 17:15
閱讀 3019·2019-08-29 16:08