摘要:參考文章多層繼承方法參考文章中提供了一個思路不一定要是一個變量也可以是一個函數(shù)只要它能返回我們期望的父級對象就可以了下面是我對它給出的源碼的一些修改和注釋另外有個測試示例要想擁有方法必須繼承類注意方法中不要再在時為子類添加指向父類本身的屬
參考文章
js多層繼承 super方法
參考文章1中提供了一個思路, _super不一定要是一個變量, 也可以是一個函數(shù), 只要它能返回我們期望的父級對象就可以了. 下面是我對它給出的源碼的一些修改和注釋, 另外有3個測試示例.
/* * @author: general * @github: https://gist.github.com/generals-space/a75cfca06e1f8d463022e0e02446c363 */ /* * 要想擁有_super()方法, 必須繼承SuperExtend類. * 注意: * 1. inherits方法中不要再在assign時為子類添加指向父類本身的屬性了, 會出問題的. * 2. 當(dāng)需要使用_super()方法調(diào)用父類的某個方法時, 必須要保證子類有同名方法, 需要通過子類的方法調(diào)用父類方法才行 */ function SuperExtend(){} SuperExtend.prototype._super = function(){ // caller調(diào)用者應(yīng)該會是子類的成員方法對象, 或是子類構(gòu)造函數(shù)本身 var caller = arguments.callee.caller; // 這里先得到this所屬的構(gòu)造函數(shù)類 var chain = this.constructor; var parent = null; // 沿繼承鏈一直向上遍歷, 至少要遍歷到SuperExtend的第一個子類 // 目標(biāo)是**找到主調(diào)函數(shù)到底屬于繼承鏈上的哪一層級, 然后才能得到這個調(diào)用者的父類, 也就是我們需要的super對象** while(chain && chain.prototype){ // 對象的隱式原型`__proto__`屬性是一個指針, 它指向**構(gòu)造本對象的**, **構(gòu)造函數(shù)類**, **的原型**. // 但是由于inherits的自定義繼承機(jī)制, chain.__proto__指向的是父級構(gòu)造函數(shù)類(chain本身為子級構(gòu)造函數(shù)類) parent = chain.__proto__; // 如果調(diào)用者正好是構(gòu)造函數(shù)類本身, 說明是在構(gòu)造函數(shù)類的函數(shù)體中調(diào)用的, // 直接返回父級構(gòu)造函數(shù)類本身 if(caller == chain) return parent; // 如果調(diào)用者不是子級構(gòu)造函數(shù)類, 就應(yīng)該是原型中的方法了. var props = Object.getOwnPropertyNames(chain.prototype); for(var i = 0; i < props.length; i ++){ // 這里雖然相等, 但有可能是當(dāng)前類從上一層父類繼承而來的屬性, 而當(dāng)前類本身并沒有定義過這個方法. // 需要進(jìn)一步確認(rèn), 即確認(rèn)父類原型上沒有與它完全相同的方法(當(dāng)然, 方法名可能一樣). if(caller == chain.prototype[props[i]] && caller != parent.prototype[props[i]]){ return parent.prototype; } } chain = parent; } return chain; }; /* * function: 自定義通用繼承方法. * 使用方法: inherits(子類, 父類) */ function inherits(subClass, superClass){ Object.assign(subClass.prototype, superClass.prototype, { constructor: subClass, }); // 建立這種聯(lián)系后, 相當(dāng)于subClass成了superClass的實(shí)例了 // 基本等價于subClass.prototype = superClass Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
3個測試示例如下
測試用例1. 基本測試// 測試用例1. 基本測試 function A(a){ this.a = a; } inherits(A, SuperExtend); A.prototype.sayHi = function(){ console.log(this.a); }; function B(a, b){ this._super().call(this, a); this.b = b; } inherits(B, A); B.prototype.sayHi = function(){ this._super().sayHi.call(this); console.log(this.a, this.b); }; function C(a, b, c){ // 這里得到的是父級構(gòu)造函數(shù)類本身, 直接call調(diào)用即可 this._super().call(this, a, b); this.c = c; } inherits(C, B); C.prototype.sayHi = function(){ // 這里得到的是父級構(gòu)造函數(shù)類的原型對象 this._super().sayHi.call(this); console.log(this.a, this.b, this.c); }; var c = new C(2, 5, 8); c.sayHi();測試用例2. 驗(yàn)證同層級函數(shù)間調(diào)用的情況
// 測試用例2. 驗(yàn)證同層級函數(shù)間調(diào)用的情況 function A(a){ this.a = a; } inherits(A, SuperExtend); A.prototype.sayA = function(){ this.sayB(); }; A.prototype.sayB = function(){ console.log(this.a); }; function B(a, b){ this._super().call(this, a); this.b = b; } inherits(B, A); B.prototype.sayB = function(){ this._super().sayB.call(this); console.log(this.a, this.b); }; function C(a, b, c){ // 這里得到的是父級構(gòu)造函數(shù)類本身, 直接call調(diào)用即可 this._super().call(this, a, b); this.c = c; } inherits(C, B); var c = new C(2, 5, 8); c.sayA();測試用例3. 驗(yàn)證主調(diào)函數(shù)與被調(diào)函數(shù)不同名的情況
// 測試用例3. 驗(yàn)證主調(diào)函數(shù)與被調(diào)函數(shù)不同名的情況 function A(a){ this.a = a; } inherits(A, SuperExtend); A.prototype.sayA = function(){ console.log(this.a); }; function B(a, b){ this._super().call(this, a); this.b = b; } inherits(B, A); B.prototype.sayB = function(){ this._super().sayA.call(this); console.log(this.a, this.b); }; function C(a, b, c){ // 這里得到的是父級構(gòu)造函數(shù)類本身, 直接call調(diào)用即可 this._super().call(this, a, b); this.c = c; } inherits(C, B); var c = new C(2, 5, 8); c.sayB();
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92862.html
摘要:參考文章多層繼承方法本系列文章對實(shí)現(xiàn)多級繼承做一個學(xué)習(xí)和探究第三篇給出最終的模擬代碼及測試用例簡單的父子繼承父類子類原型鏈繼承這里我用了關(guān)鍵字表示了繼承的父類方法可以將其附加到子類實(shí)例對象上用起來會方便一點(diǎn)但是比較致命的一點(diǎn)是這種方式不適 參考文章 js多層繼承 super方法 本系列文章對js es5實(shí)現(xiàn)多級繼承做一個學(xué)習(xí)和探究, 第三篇給出最終的模擬代碼及測試用例. 簡單的父-子繼...
摘要:參考文章官網(wǎng)是一個的編譯器它可以將的代碼轉(zhuǎn)換成等價的我們看看它是怎么模擬關(guān)鍵字的與上面等價的語句如下貌似不支持多重繼承啊覆寫子類的對象設(shè)置隱式原型感覺這樣很怪因?yàn)檫@樣意為著子類將成為父類的實(shí)例對象呃類似的概念但我不覺得父子類關(guān)系與類和實(shí) 參考文章 Babel官網(wǎng) babel是一個es6->es5的編譯器, 它可以將es6的代碼轉(zhuǎn)換成等價的es5. 我們看看它是怎么模擬super關(guān)鍵字的...
摘要:歡迎關(guān)注我的博客正文讓我來構(gòu)造函數(shù)其實(shí),模擬一個類的方式非常的簡單構(gòu)造函數(shù)。我們先來看一個例子這里通過構(gòu)造函數(shù)模擬出來的類,其實(shí)和其他語言的類行為上是基本一致的,唯一的區(qū)別就是它不具備私有方法。 前言 ES6時代的來臨,使得類繼承變得如此的圓滑。但是,你有思考過ES6的類繼承模式嗎?如何去實(shí)現(xiàn)它呢? 類繼承對于JavaScript來說,實(shí)現(xiàn)方式與Java等類語言大不相同。熟悉JavaS...
摘要:接下來我們看下類的寫法,這個就很接近于傳統(tǒng)面向?qū)ο笳Z言了。如果你想了解傳統(tǒng)面向?qū)ο笳Z言,這里是一個好切入點(diǎn)。作為對象時,指向父類的原型對象。這些就是為將來在中支持面向?qū)ο蟮念悪C(jī)制而預(yù)留的。 在ES5中,我們經(jīng)常使用方法或者對象去模擬類的使用,并基于原型實(shí)現(xiàn)繼承,雖然可以實(shí)現(xiàn)功能,但是代碼并不優(yōu)雅,很多人還是傾向于用 class 來組織代碼,很多類庫、框架創(chuàng)造了自己的 API 來實(shí)現(xiàn) c...
摘要:父類中的訪問權(quán)限一定要小于或者等于子類訪問權(quán)限的個關(guān)鍵字訪問權(quán)限大小,其中為默認(rèn)值,不用寫。下面是一個典型的代碼父類代碼子類代碼測試類代碼輸出結(jié)果在子類那里已經(jīng)表明。 繼承(Extends)1、前言還是先說一下博主本人的一些基本情況吧。本人去年剛剛畢業(yè),專業(yè)是電氣工程及其自動化,就是在大學(xué)期間完全沒有接觸過JAVA,也就稍稍了解了一下C語言。后來找了現(xiàn)在的工作也是和編程沒有任何關(guān)系,是...
閱讀 2810·2019-08-30 15:55
閱讀 2857·2019-08-30 15:53
閱讀 2294·2019-08-26 13:47
閱讀 2557·2019-08-26 13:43
閱讀 3154·2019-08-26 13:33
閱讀 2802·2019-08-26 11:53
閱讀 1796·2019-08-23 18:35
閱讀 798·2019-08-23 17:16