摘要:這又是什么呢這個相對之前的比較復雜,但是高效的一點是只調用一次被繼承者構造函數原理就是通過寄生方式創建一個被繼承者的副本,副本和被繼承者共用一個這樣就解決了之前的問題返回的一個副本設置指向因為新副本的原型對象被重寫副本作為的原型對象
前言
我們學JAVA的時候說到繼承就是一個extends ClassName的事情,但是在JS的世界里繼承和我們在JAVA所認識的繼承實現方法又有一些不同,你們真的了解JS的繼承嗎?就當你們很了解了,畢竟是基礎知識,我就簡單說說
原型鏈繼承簡言之就是把被繼承的對象賦值給繼承者的原型對象
function Super() { this.name = "mirok"; } Super.prototype.showName = function () { console.log(this.name); } function Sub() { this.name = "july"; } Sub.prototype = new Super(); const obj = new Sub(); obj.showName(); //輸出july
原型實現繼承雖然可以,但是也有相應的弊端,例如new Super()構建多個實例,繼承里面的方法被其中一個實例重寫,就會影響其他實例,也就是說原型里的是所有實例所共享的,這是我們不愿看到的,因此就有以下的方法。
借用構造函數簡言之就是在繼承者的構造函數中去調用被繼承者的構造函數(即使用apply()/call()實現)
function Super() { this.supername = "mirok"; } function Sub() { Super.call(this) this.name = "july"; } Sub.prototype = new Super(); const obj = new Sub(); obj.name; //july obj.supername; //mirok
這種方式實現的繼承相對于之前的來說不僅解決了之前的問題還能向被繼承者傳參數,但是也有一定的弊端,即容易覆蓋本身的屬性,解決方法就是在調用被繼承者的構造函數再對自己添加屬性,也就是說上面的Super.call要在this.name定義屬性之前。另一個弊端就是繼承的是無法共享的
組合繼承這個就是組合前面的原型鏈繼承和借用構造函數繼承兩者之長,也就是說既能在繼承后的實例都有一份屬性又能共用
function Super() { this.name = "mirok"; } Super.prototype.showName = function () { console.log(this.name); } function Sub1() { Super.call(this); this.name = "july"; } function Sub2() { Super.call(this); this.name = "deny"; } Sub1.prototype = new Super(); Sub2.prototype = new Super(); const obj1 = new Sub1(); const obj2 = new Sub2(); obj1.showName(); // july obj2.showName(); // deny原型式繼承
這個比較特殊一點,就是在一個函數里去做原型鏈繼承的事情
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); }
ES5規范了這類寫法,就是Object.create(),但是弊端和第一種類似,因為不是我們理想的繼承這里就不詳細介紹
寄生式繼承這個也比較特殊,就是把繼承的事情放在一個函數里去做,再把對象返回
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); } function factory() { const person = {name:"mirok", age: 22}; const obj = object(person); obj.show = function() {console.log(this.name)} return obj; } factory().show(); //"mirok"
至于弊端可見而知,不能實現共享
寄生組合式繼承組合繼承有個弊端就是會調用兩次被繼承者的構造函數,解決方法就是使用寄生組合式繼承。這又是什么呢?這個相對之前的比較復雜,但是高效的一點是只調用一次被繼承者構造函數,原理就是通過寄生方式創建一個被繼承者的副本,副本和被繼承者共用一個prototype,這樣就解決了之前的問題
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); } function factory(Sub, Super) { var proto = object(Super.prototype); //返回Super的一個副本 proto.constructer = Sub; //設置constructor指向, 因為新副本的原型對象被重寫 Sub.prototype = proto; //副本作為sub的原型對象 } function Super () { this.name = "july"; } Super.prototype.show = function () { console.log(this.name); } function Sub1 () { Super.call(this); this.name = "mirok" } function Sub2 () { Super.call(this); this.name = "deny" } factory(Sub1, Super); factory(Sub2, Super); var obj1 = new Sub1(); var obj2 = new Sub2(); obj1.show(); // mirok obj2.show(); // deny
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96757.html
摘要:前言還記得當初用語言寫各種數據結構的苦逼時代嘛,但是用來實現棧和隊列是如此的簡單啊,但是你們真的了解用模擬棧和隊列,就當你們真的很了解了,畢竟是基礎知識,我就寫幾個案例,不喜勿噴棧棧方法棧就是先進后出,就是如此便捷就可以簡單實現棧隊列隊列是 前言: 還記得當初用C語言寫各種數據結構的苦逼時代嘛,但是用JS來實現棧和隊列是如此的簡單啊,但是你們真的了解用js模擬棧和隊列,就當你們真的很了...
摘要:我們知道創建了一個函數就帶了一個屬性,創建一個實例就帶著一個指針,這個指針是實例和構造函數的原型對象間的聯系,這個指針在腳本中是不可見的,也就是你不能訪問的,但是在和中,提供了來支持訪問,這么一說,相信大家應該能明白吧 前言 一般我們看到prototype就會下意識的說這不就是原型對象嘛?但是你們真的了解prototype嘛?就當你們很了解了,畢竟是基礎知識,我就簡單說說 正文 先說說...
摘要:使用原型鏈實現對原型屬性和方法的繼承,用借用構造函數模式實現對實例屬性的繼承。 我們之前介紹了javascript面向對象的封裝的相關內容,還介紹了js的call方法,今天開始討論js的繼承這篇文章參考了《javascript高級程序設計》(第三版),但內容不局限于,網上很多關于js繼承的相關內容都是來自于這本書,有興趣的同學可以翻閱查看 原型鏈繼承 我們先通過一個栗子,了解一下原型鏈...
摘要:前言函數傳參我們天天都在用,但是你們真的了解嘛就當你們很了解了,畢竟是一些基礎的東西,我就寫幾個例子,不喜勿噴。 前言 函數傳參我們天天都在用,但是你們真的了解嘛?就當你們很了解了,畢竟是一些基礎的東西,我就寫幾個例子,不喜勿噴。 例子 demo1: var obj = {name: mirok} function demo1(obj) { obj.name = july }...
摘要:面試官要不你來手寫下單例模式唄候選者單例模式一般會有好幾種寫法候選者餓漢式簡單懶漢式在方法聲明時加鎖雙重檢驗加鎖進階懶漢式靜態內部類優雅懶漢式枚舉候選者所謂餓漢式指的就是還沒被用到,就直接初始化了對象。面試官:我看你的簡歷寫著熟悉常見的設計模式,要不你來簡單聊聊你熟悉哪幾個吧?候選者:常見的工廠模式、代理模式、模板方法模式、責任鏈模式、單例模式、包裝設計模式、策略模式等都是有所了解的候選者:...
閱讀 1846·2021-08-19 11:12
閱讀 1423·2021-07-25 21:37
閱讀 986·2019-08-30 14:07
閱讀 1265·2019-08-30 13:12
閱讀 649·2019-08-30 11:00
閱讀 3527·2019-08-29 16:28
閱讀 987·2019-08-29 15:33
閱讀 2965·2019-08-26 13:40