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