你們好,我是蘇日儷格,本文是面向對象的第四部分,純屬我的理解,有哪裏不對的地方請在評論區指出,你們一塊兒學習共同進步。前端
下面來看一下對象繼承都有哪些方式:web
原型鏈是面向對象中最多見最簡單的,所謂原型鏈就是用父類實例來充當子類原型的對象
直接走栗子:
編程
function Father(){ this.aInfo = ['蘇日儷格', 'web前端開發']; } function Child(){} Child.prototype = new Father(); let child = new Child(); console.log(child.aInfo) // ["蘇日儷格", "web前端開發"] child.aInfo.push(24); console.log(child.aInfo) // ["蘇日儷格", "web前端開發", 24] let child2 = new Child(); console.log(child2.aInfo) // ["蘇日儷格", "web前端開發", 24]
優勢:簡單易懂
缺點:因爲這種原型鏈式繼承實例以前共享了屬性,因此在修改屬性值的時候是存在引用的;還有個問題就是在建立實例的時候,沒法給父類型構造函數中傳遞參數,所以通常不單獨用原型鏈app
這個時候面向對象的老闆娘來了,笑着對大佬說了一句,想加薪不,想的話就加一下班處理一下,因而乎大佬們研究出了借用構造函數的繼承方式 ↓↓↓函數
鑑於原型鏈的問題,就出現了借用構造函數的方式,就是在子類型的構造函數中調用超類型的構造函數,來實現繼承,在調用的過程當中,須要用apply或call方法來改變this的指向問題學習
function Father(){ this.aInfo = ['蘇日儷格', 'web前端開發']; } function Child(){ Father.call(this); } Child.prototype = new Father(); let child = new Child(); console.log(child.aInfo) // ["蘇日儷格", "web前端開發"] child.aInfo.push(24); console.log(child.aInfo) // ["蘇日儷格", "web前端開發", 24] let child2 = new Child(); console.log(child2.aInfo) // ["蘇日儷格", "web前端開發"]
function Father(name){ this.aInfo = name; } function Child(age){ Father.call(this, ['蘇日儷格', 'web前端開發']); this.age = age; } Child.prototype = new Father(); let child = new Child(24); console.log(child.aInfo) // ["蘇日儷格", "web前端開發"] console.log(child.age) // 24
優勢:解決了原型鏈式存在的問題
缺點:代碼複用性差,函數複用沒辦法解決,若是子類型構造函數過多,會致使內存泄漏的問題,所以這種方式也不多單獨使用this
這個時候面向對象的老闆娘她又來了,面帶不太天然的微笑剛準備開口說話,大佬說我加一下班處理一下,因而乎大佬們又研究出了組合繼承的繼承方式 ↓↓↓prototype
這就和建立對象時候使用的混合模式實際上是一個道理,就是將原型鏈和借用構造函數結合,發揮兩者的優勢取長補短,實現共享方法不共享屬性code
function Person(name){ this.aInfo = name; } Person.prototype.show = function(){ console.log(this.aInfo); }; function Child(name, age){ Person.call(this, name); this.age = age; } Child.prototype = new Person(); Child.prototype.constructor = Child; Child.prototype.showAge = function(){ console.log(this.age); }; let child1 = new Child(['蘇日儷格', 'web前端開發'], 24); child1.show(); // ["蘇日儷格", "web前端開發"] child1.aInfo.push('男'); child1.show(); // ["蘇日儷格", "web前端開發", "男"] child1.showAge(); // 24 let child2 = new Child(['趙雲', '救阿斗'], 27); child2.show(); // ["趙雲", "救阿斗"] child2.showAge(); // 27
優勢:融合兩者優勢於一身,也是最經常使用的一種繼承方式
缺點:雖然是最經常使用的一種繼承方式,可是也有一丟丟瑕疵,就是不管什麼狀況下,都會調用兩次超類型構造函數,在第一次call的時候,把父類型的實例屬性拷貝了一份給子類實例屬性,而這個屬性根本就是活着浪費空氣死了浪費土地型的,所以致使的原型引用屬性在實例間共享;不過到這裏,其實能感受到就是一個小瑕疵,因此通常碼農門也不會考慮它,畢竟相對於這一丁點劣勢仍是值得的。對象
這個時候面向對象的老闆娘她仍是來了,陰險的笑容立刻就漏出來了,因而大佬們冷靜的喝了一杯茶,回過頭仍是研究出了最佳的繼承方式,就是寄生組合式繼承法,這個方法也是目前的終極版了,各類優勢體現的淋漓盡致,可是也有一個缺點就是理解起來編程的過程當中有些複雜,別問我,由於我不想加薪(’ー’),因此就沒看,想看的本身去問度娘吧(~ ̄▽ ̄)~
本文的全部內容均是一字一句敲上去的,但願你們閱讀完本文能夠有所收穫,由於能力有限,掌握的知識也是不夠全面,歡迎你們提出來一塊兒分享!謝謝O(∩_∩)O~