reopen不知道怎麼翻譯了,若是按照reopen翻譯過來應該是「從新打開」,可是總以爲不順,因此就換成「擴展」了。當你想擴展一個類你能夠直接使用reopen()方法爲一個已經定義好的類添加屬性、重寫類裏的方法。若是是使用extend()方法你須要從新定義一個子類,而後在子類中添加新的屬性、方法。ubuntu
前一篇所過,調用create()方法時候不能傳入的參數屬性名稱必需要跟類成員一致,可是使用reopen()方法能夠傳入新的參數。與extend()方法很是類似,下面的代碼演示了它們的不一樣之處。vim
Parent = Ember.Object.extend({ name: 'ubuntuvim', fun1() { console.log("The name is " + this.name); }, common() { console.log("common method..."); } }); // 使用extend()方法添加新的屬性、方法 Child1 = Parent.extend({ // 給類Parent爲新增一個屬性 pwd: '12345', // 給類Parent爲新增一個方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重寫父類的common()方法 common() { //console.log("override common method of parent..."); this._super(); } }); var c1 = Child1.create(); console.log("name = " + c1.get('name') + ", pwd = " + c1.get('pwd')); c1.fun1(); c1.fun2(); c1.common(); console.log("-----------------------"); // 使用reopen()方法添加新的屬性、方法 Parent.reopen({ // 給類Parent爲新增一個屬性 pwd: '12345', // 給類Parent爲新增一個方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重寫類自己common()方法 common() { console.log("override common method by reopen method..."); //this._super(); } }); var p = Parent.create(); console.log("name = " + p.get('name') + ", pwd = " + p.get('pwd')); p.fun1(); p.fun2(); p.common(); console.log("---------------------------"); // 使用extend()方法添加新的屬性、方法 Child2 = Parent.extend({ // 給類Parent爲新增一個屬性 pwd: '12345', // 給類Parent爲新增一個方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重寫父類的common()方法 common() { //console.log("override common method of parent..."); this._super(); } }); var c2 = Child2.create(); console.log("name = " + c2.get('name') + ", pwd = " + c2.get('pwd')); c2.fun1(); c2.fun2(); c2.common();
從執行結果能夠看到以下的差別:app
同點:ide
均可以用於擴展某個類。性能
異點:網站
extend須要從新定義一個類而且要繼承被擴展的類;this
reopen是在被擴展的類自己上新增屬性、方法;編碼
到底用那個方法有實際狀況而定,reopen方法會改變了原類的行爲,就如演示實例同樣在reopen方法以後調用的Child2類的common方法的行爲已經改改變了,在編碼過程忘記以前已經調用過reopen方法就有可能出現本身都不知道怎麼回事的問題!spa
若是是extend方法會致使類愈來愈多,繼承樹也會愈來愈深,對性能、調試也是一大挑戰,可是extend不會改變被繼承類的行爲。翻譯
使用reopenClass()方法能夠擴展static類型的屬性、方法
Parent = Ember.Object.extend(); // 使用reopenClass()方法添加新的static屬性、方法 Parent.reopenClass({ isPerson: true, // name: '123' // 不能設置String類型的屬性!!!,報Uncaught TypeError: Cannot assign to read only property 'name' }); Parent.reopen({ isPerson: false, name: 'ubuntuvim' }); console.log(Parent.isPerson); console.log(Parent.name); // 輸出空 console.log(Parent.create().get('isPerson')); console.log(Parent.create().get('name')); // 輸出 ubuntuvim
可是有個疑問是reopenClass()新增string類型的屬性時候提示不容許!!!官網教程也沒說明這個問題,估計是代碼有問題。有時間看看是怎麼回事……