摘要:使用原型鏈實現對原型屬性和方法的繼承,用借用構造函數模式實現對實例屬性的繼承。
我們之前介紹了javascript面向對象的封裝的相關內容,還介紹了js的call方法,今天開始討論js的繼承
這篇文章參考了《javascript高級程序設計》(第三版),但內容不局限于,網上很多關于js繼承的相關內容都是來自于這本書,有興趣的同學可以翻閱查看
我們先通過一個栗子,了解一下原型鏈繼承。留意代碼注釋內容
//創建自定義構造函數 function Hqg() { this.name = "洪七公"; } //在當前構造函數的原型鏈上添加屬性skill Hqg.prototype.skill = "打狗棒" //通過自定義構造函數Hqg實例化一個對象gj const gj = new Hqg() console.log(gj.skill);//=>打狗棒 //通過自定義構造函數Hqg實例化一個對象hr const hr = new Hqg() console.log(hr.skill);//=>打狗棒
一個簡單的栗子,郭靖和黃蓉都從洪七公那里繼承到了skill 打狗棒,貌似沒什么問題,我們繼續看demo
//上面代碼省略 const gj = new Hqg()//通過自定義構造函數Hqg實例化一個對象gj gj.skill = "降龍十八掌"http://重新對gj的skill賦值 console.log(gj.skill);//=>降龍十八掌 //通過自定義構造函數Hqg實例化一個對象hr const hr = new Hqg() console.log(hr.skill);//=>打狗棒
對郭靖的skill重新賦值,也沒有影響黃蓉的skill,我們打印一下gj
gj的skill屏蔽掉了原型鏈上的skill,所以gj的skill是降龍十八掌,而hr的skill依然是打狗棒
function Hqg() { this.name = "洪七公"; } Hqg.prototype.skill = ["打狗棒"] const gj = new Hqg() gj.skill.push ("降龍十八掌")//找到了原型鏈中的skill,并對其執行push操作,從而改變了構造函數中的skill屬性 console.log(gj.skill); //=>["打狗棒", "降龍十八掌"] const hr = new Hqg() //構造函數中的skill已經被改變 console.log(hr.skill); //=>["打狗棒", "降龍十八掌"]
總結一下,gj和hr都是Hqg的實例,繼承Hqg的屬性和方法,當Hqg的屬性或者方被改變了,后面的實例也會受影響,有時候這并不是我們希望的結果
借用構造函數借用?就是使用call或者apply改變一下this指向,
就是子類的構造函數內部通過call或者apply調用父類的構造函數,如果對call方法有不了解的地方,可以翻看昨天的文章
舉一個栗子
//創建一個構造函數,并添加一些屬性 function Hqg() { this.name = "洪七公"; this.job = "幫主"; this.skill = ["降龍十八掌", "打狗棒"] } //創建一個構造函數,并借用了Hqg的構造函數 function Hr() { Hqg.call(this) this.name = "黃蓉"; this.job = ["相夫", "教子"] } //創建一個構造函數,并借用了Hqg的構造函數 function Gj() { Hqg.call(this) this.name = "郭靖"; this.job = ["吃飯", "睡覺"] } const hr = new Hr(); console.log(hr); const gj = new Gj(); console.log(gj);
輸出
這樣就避免了原型鏈繼承中,構造函數中的屬性或者方法被其他實例所改變的問題
??:這里要注意call方法的執行順序:
//部分代碼省略 function Hr() { this.name = "黃蓉"; this.job = ["相夫", "教子"] Hqg.call(this) } function Gj() { this.name = "郭靖"; this.job = ["吃飯", "睡覺"] Hqg.call(this) } //部分代碼省略
如果call在之后執行就會導致一個問題
值會被覆蓋,這個要注意!
這個算是一個升級的玩法吧
function Hqg(name,job,skill) { this.name = name; this.job = job; this.skill = skill } function Hr() { Hqg.call(this,"黃蓉",["相夫", "教子"],["打狗棒"]) } function Gj() { Hqg.call(this,"郭靖",["吃飯", "睡覺"],["降龍十八掌"]) } const hr = new Hr(); console.log(hr); const gj = new Gj(); console.log(gj);
輸出
將原型鏈和借用構造函數技術組合到一起。
使用原型鏈實現對原型屬性和方法的繼承,用借用構造函數模式實現對實例屬性的繼承。
這樣既通過在原型上定義方法實現了函數復用,又能保證每個實例都有自己的屬性
一個栗子
function Hqg(name) { this.name = name this.skill = ["降龍十八掌","打狗棒"] } Hqg.prototype.sayName = function () { console.log(this.name); } function Hero(name, job) { Hqg.call(this, name); this.job = job } Hero.prototype = new Hqg(); Hero.prototype.constructor = Hero; Hero.prototype.sayJob = function () { console.log(this.job) } var gj = new Hero("郭靖", "吃飯睡覺"); gj.skill.push("九陰真經"); console.log(gj); var hr = new Hero("黃蓉", "相夫教子"); console.log(hr);
先看下輸出
我們把這個組合繼承和之前的兩個原型鏈繼承和借用構造函數繼承進行比較
不難發現組合繼承融合了他們的優點,成為javascript中最常用的繼承模式
今天就討論前三個,還有三個明天繼續,不見不散
參考鏈接
你們真的了解JS的繼承嘛?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100165.html
摘要:之前,本質上不能算是一門面向對象的編程語言,因為它對于封裝繼承多態這些面向對象語言的特點并沒有在語言層面上提供原生的支持。所以在中出現了等關鍵字,解決了面向對象中出現了問題。 ES6之前,javascript本質上不能算是一門面向對象的編程語言,因為它對于封裝、繼承、多態這些面向對象語言的特點并沒有在語言層面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以讓我們以...
摘要:那你們肯定會問為什么共用,而沒有共用呢,下面就給你解釋,請看引用類型是共用的值類型是私用的。 引言 面向對象的編程語言都具繼承這一機制,而 JavaScript 是基于原型(Prototype)面向對象程序設計,所以它的實現方式也是基于原型(Prototype)實現的. 繼承的方式 類式繼承 構造函數繼承 組合繼承 原型式繼承 寄生式繼承 寄生組合式繼承 1.類式繼承 //聲明父...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:實現思路使用原型鏈實現對原型方法和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承。繼承屬性繼承方法以上代碼,構造函數定義了兩個屬性和。 JS面向對象的程序設計之繼承的實現-組合繼承 前言:最近在細讀Javascript高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯誤,會非常感謝您的指出。文中絕大部分內容引用自《Java...
閱讀 3423·2021-11-24 09:39
閱讀 1811·2021-11-17 09:33
閱讀 3541·2021-10-12 10:12
閱讀 5048·2021-09-22 15:51
閱讀 1123·2019-08-30 13:11
閱讀 3584·2019-08-30 10:59
閱讀 578·2019-08-30 10:48
閱讀 1324·2019-08-26 13:48