摘要:參考文章多層繼承方法本系列文章對實(shí)現(xiàn)多級(jí)繼承做一個(gè)學(xué)習(xí)和探究第三篇給出最終的模擬代碼及測試用例簡單的父子繼承父類子類原型鏈繼承這里我用了關(guān)鍵字表示了繼承的父類方法可以將其附加到子類實(shí)例對象上用起來會(huì)方便一點(diǎn)但是比較致命的一點(diǎn)是這種方式不適
參考文章
js多層繼承 super方法
本系列文章對js es5實(shí)現(xiàn)多級(jí)繼承做一個(gè)學(xué)習(xí)和探究, 第三篇給出最終的模擬代碼及測試用例.
簡單的父-子繼承// 父類A function A(a){ this.a = a; } A.prototype.sayA = function(){ console.log(this.a); }; // 子類B function B(a, b){ this._super.call(this, a); this.b = b; } // 原型鏈繼承 Object.assign(B.prototype, A.prototype, { constructor: B, _super: A }); B.prototype.sayB = function(){ console.log(this.b); }; var b = new B(1, 2); b.sayA(); // 1 b.sayB(); // 2
這里我用了_super關(guān)鍵字表示了繼承的父類, Object.assign()方法可以將其附加到子類實(shí)例對象上, 用起來會(huì)方便一點(diǎn).
但是, 比較致命的一點(diǎn)是, 這種方式不適用于多級(jí)繼承, 我所定義的_super反而成了限制.
// 父類A function A(a){ this.a = a; } A.prototype.sayA = function(){ console.log(this.a); }; // 子類B function B(a, b){ this._super.call(this, a); this.b = b; } // 原型鏈繼承 Object.assign(B.prototype, A.prototype, { constructor: B, _super: A }); B.prototype.sayB = function(){ console.log(this.b); }; // 子類C function C(a, b, c){ this._super.call(this, a, b); this.c = c; } // 原型鏈繼承 Object.assign(C.prototype, B.prototype, { constructor: C, _super: B }); C.prototype.sayC = function(){ console.log(this.c); }; var c = new C(1, 2, 3); c.sayA(); c.sayB(); c.sayC();
上面的代碼看起來似乎沒什么錯(cuò)誤, 但是執(zhí)行時(shí), 會(huì)棧溢出, 在B類函數(shù)體的this._super.call(this, a);這一行.
VM4484:10 Uncaught RangeError: Maximum call stack size exceeded at C.B [as _super] (:10:11) at C.B [as _super] ( :11:17)
原因在于, c在實(shí)例化時(shí)構(gòu)造函數(shù)調(diào)用父類B的構(gòu)造函數(shù), 但用的是call方法, B類構(gòu)造函數(shù)在執(zhí)行時(shí)this的值為c的實(shí)例, 而this._super的值又是B, 于是就在B的構(gòu)造函數(shù)里一直循環(huán).
要解決這個(gè)問題, _super變量就不能綁定在this上, 但是好像也沒有好的方法綁定在子類本身, 除非在子類中用父類的類名顯示調(diào)用父類的同名方法. 但這樣耦合性太強(qiáng), 稍不注意就會(huì)出錯(cuò)(尤其是代碼復(fù)制時(shí)).
參考文章1中有錯(cuò)誤, 不存在__super__屬性, 但它給了我一個(gè)啟示, super不一定非得是變量, 也可以是一個(gè)函數(shù), 由函數(shù)的執(zhí)行結(jié)果作為父類對象也是一種方法.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92835.html
摘要:參考文章官網(wǎng)是一個(gè)的編譯器它可以將的代碼轉(zhuǎn)換成等價(jià)的我們看看它是怎么模擬關(guān)鍵字的與上面等價(jià)的語句如下貌似不支持多重繼承啊覆寫子類的對象設(shè)置隱式原型感覺這樣很怪因?yàn)檫@樣意為著子類將成為父類的實(shí)例對象呃類似的概念但我不覺得父子類關(guān)系與類和實(shí) 參考文章 Babel官網(wǎng) babel是一個(gè)es6->es5的編譯器, 它可以將es6的代碼轉(zhuǎn)換成等價(jià)的es5. 我們看看它是怎么模擬super關(guān)鍵字的...
摘要:參考文章多層繼承方法參考文章中提供了一個(gè)思路不一定要是一個(gè)變量也可以是一個(gè)函數(shù)只要它能返回我們期望的父級(jí)對象就可以了下面是我對它給出的源碼的一些修改和注釋另外有個(gè)測試示例要想擁有方法必須繼承類注意方法中不要再在時(shí)為子類添加指向父類本身的屬 參考文章 js多層繼承 super方法 參考文章1中提供了一個(gè)思路, _super不一定要是一個(gè)變量, 也可以是一個(gè)函數(shù), 只要它能返回我們期望的父...
摘要:歡迎關(guān)注我的博客正文讓我來構(gòu)造函數(shù)其實(shí),模擬一個(gè)類的方式非常的簡單構(gòu)造函數(shù)。我們先來看一個(gè)例子這里通過構(gòu)造函數(shù)模擬出來的類,其實(shí)和其他語言的類行為上是基本一致的,唯一的區(qū)別就是它不具備私有方法。 前言 ES6時(shí)代的來臨,使得類繼承變得如此的圓滑。但是,你有思考過ES6的類繼承模式嗎?如何去實(shí)現(xiàn)它呢? 類繼承對于JavaScript來說,實(shí)現(xiàn)方式與Java等類語言大不相同。熟悉JavaS...
摘要:父類中的訪問權(quán)限一定要小于或者等于子類訪問權(quán)限的個(gè)關(guān)鍵字訪問權(quán)限大小,其中為默認(rèn)值,不用寫。下面是一個(gè)典型的代碼父類代碼子類代碼測試類代碼輸出結(jié)果在子類那里已經(jīng)表明。 繼承(Extends)1、前言還是先說一下博主本人的一些基本情況吧。本人去年剛剛畢業(yè),專業(yè)是電氣工程及其自動(dòng)化,就是在大學(xué)期間完全沒有接觸過JAVA,也就稍稍了解了一下C語言。后來找了現(xiàn)在的工作也是和編程沒有任何關(guān)系,是...
摘要:常用繼承方式主要分為種原型鏈繼承構(gòu)造函數(shù)繼承組合繼承原型式繼承寄生式繼承寄生組合繼承以及繼承多個(gè)對象。所以說,構(gòu)造函數(shù)基礎(chǔ)只能繼承父類的實(shí)例屬性和方法,不能繼承原型鏈上的屬性和方法。 JavaScript常用繼承方式主要分為(7種):原型鏈繼承、構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承、寄生組合繼承以及繼承多個(gè)對象。 1:原型鏈繼承(核心:將父類的實(shí)例作為子類的原型) 基本概念:...
閱讀 2053·2021-11-11 16:55
閱讀 1395·2021-09-28 09:36
閱讀 1038·2019-08-29 15:21
閱讀 1572·2019-08-29 14:10
閱讀 2757·2019-08-29 14:08
閱讀 1628·2019-08-29 12:31
閱讀 3243·2019-08-29 12:31
閱讀 976·2019-08-26 16:47