JavaScript ES6 class多重繼承實踐與總結(jié)

ES6中,class原生是不支持多重繼承的炸庞,根據(jù)阮一峰ES6參考資料中的方法,通過以下方式即可實現(xiàn)class繼承多個類:

function mix(...mixins) {
  class Mix {}

  for (let mixin of mixins) {
    copyProperties(Mix, mixin);
    copyProperties(Mix.prototype, mixin.prototype);
  }

  return Mix;
}

function copyProperties(target, source) {
  for (let key of Reflect.ownKeys(source)) {
    if ( key !== "constructor"&& key !== "prototype"&& key !== "name") {
      let desc = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, desc);
    }
  }
}

根據(jù)實踐荚斯,這樣做有一個很大的問題埠居,文中沒有提到,參考MDN后事期,發(fā)現(xiàn)MDN對于此處也沒有詳細(xì)的解答滥壕。
請看以下代碼:

 class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    introduce() {
        return `My name is ${this.name}. I am ${this.age} years old.`;
    }
};
//已經(jīng)引入了node的EventEmitter類
//現(xiàn)在通過Person和EventEmitter這兩個類,創(chuàng)建Mix類兽泣。
let Mix = mix(Person,EventEmitter);

//創(chuàng)建一個新類Teacher绎橘,繼承Mix類(理想狀況下是繼承了Person,EventEmitter這兩個類,并且能夠調(diào)用父類的構(gòu)造器)
class Teacher extends Mix {
    constructor(name,id){
        super(name,id);//此處出現(xiàn)問題唠倦,父類的構(gòu)造器是空的
    }
}
var teacher1 = Teacher("tom",21);

理想狀況下称鳞,teacher1.name == 'tom'還有teacher1.age = 21,并且teacher1還繼承了Person和Eventemitter的方法稠鼻,然而實際結(jié)果是teacher1.name 和 teacher1.age都是undefined冈止,打斷點調(diào)試后,發(fā)現(xiàn)問題所在候齿,constructor在mix函數(shù)中并沒有被拷貝熙暴,因為混合多個類的時候,mix函數(shù)并不知道應(yīng)該以哪個父類的constructor作為子類的constructor,所以在copyProperties函數(shù)中慌盯,跳過了這個屬性的拷貝:

if ( key !== "constructor"&& key !== "prototype"&& key !== "name") {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}

更改copyProperties函數(shù)使混合后的Mix類constructor為Person的constructor后周霉,不知道是什么機制導(dǎo)致,MIx的constructor還是為空亚皂,
此時我求助于Stack Overflow:鏈接俱箱。
根據(jù)其中解答,我總結(jié)了以下幾點:

  • 首先孕讳,在JavaScript實現(xiàn)多重繼承的時候匠楚,考慮是否程序設(shè)計上的不合理(最后發(fā)現(xiàn)確實是有別的途徑不通過多重繼承實現(xiàn)同樣功能)
  • 在ES5中,子類多重繼承父類厂财,調(diào)用父類的構(gòu)造函數(shù),可以用以下方法:
function Foo(...args) {
   let _this = this;
   _this = Bar.apply(_this, args);
   _this = Baz.apply(_this, args);
   return _this;
}
  • 在ES6中峡懈,以上做法不可行:

This won't work if Bar or Baz is ES6 class because it contains a mechanism that prevents it from being called without new. In this case they should be instantiated:

  • 此處是ES6類的寫法與ES5不同的一點)璃饱,正確的做法應(yīng)該是:
 constructor(...args) {
   super(...args)

   EventEmitter.call(this);//因為EventEmitter并不是ES6構(gòu)造的,可以當(dāng)做普通函數(shù)調(diào)用
   // or
   // EventEmitter.init.call(this);
}
copyProperties(Foo.prototype, EventEmitter.prototype);

結(jié)合本題

class Teacher extends Person{
    constructor(name,age,clazzes){
         super(name,age);
         EventEmitter.call(this);
         \\...
}

問題解決

(最后發(fā)現(xiàn)并不需要多重繼承肪康,直接讓Class(班級)繼承EventEmitter就可以了)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荚恶,一起剝皮案震驚了整個濱河市撩穿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谒撼,老刑警劉巖食寡,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異廓潜,居然都是意外死亡抵皱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門辩蛋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呻畸,“玉大人,你說我怎么就攤上這事悼院∩宋” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵据途,是天一觀的道長绞愚。 經(jīng)常有香客問我,道長颖医,這世上最難降的妖魔是什么爽醋? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮便脊,結(jié)果婚禮上蚂四,老公的妹妹穿的比我還像新娘。我一直安慰自己哪痰,他們只是感情好遂赠,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晌杰,像睡著了一般跷睦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肋演,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天抑诸,我揣著相機與錄音,去河邊找鬼爹殊。 笑死蜕乡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梗夸。 我是一名探鬼主播层玲,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辛块?” 一聲冷哼從身側(cè)響起畔派,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎润绵,沒想到半個月后线椰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡尘盼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年憨愉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悔叽。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡莱衩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娇澎,到底是詐尸還是另有隱情笨蚁,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布趟庄,位于F島的核電站括细,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏戚啥。R本人自食惡果不足惜奋单,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望猫十。 院中可真熱鬧览濒,春花似錦、人聲如沸拖云。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宙项。三九已至乏苦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尤筐,已是汗流浹背汇荐。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盆繁,地道東北人掀淘。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像改基,于是被迫代替她去往敵國和親繁疤。 傳聞我的和親對象是個殘疾皇子咖为,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • class的基本用法 概述 JavaScript語言的傳統(tǒng)方法是通過構(gòu)造函數(shù)秕狰,定義并生成新對象稠腊。下面是一個例子: ...
    呼呼哥閱讀 4,092評論 3 11
  • 本文先對es6發(fā)布之前javascript各種繼承實現(xiàn)方式進行深入的分析比較,然后再介紹es6中對類繼承的支持以及...
    lazydu閱讀 16,680評論 7 44
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法鸣哀,類相關(guān)的語法架忌,內(nèi)部類的語法,繼承相關(guān)的語法我衬,異常的語法叹放,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 強大的for-of循環(huán) ES6不會破壞你已經(jīng)寫好的JS代碼。目前看來挠羔,成千上萬的Web網(wǎng)站依賴for-in循環(huán)井仰,其...
    Awe閱讀 7,515評論 2 7
  • 早上把昨天閱讀的"損失規(guī)避"重新復(fù)讀了一遍,之后把第五節(jié)"價格錨點"聽一遍讀一遍破加,這是算是粗略地把劉潤老師的第一周...
    思維峰哥閱讀 262評論 0 0