Ember 類的擴(kuò)展

2018-01-06 16:47 更新

擴(kuò)展一般屬性

reopen不知道怎么翻譯好,如果按照reopen翻譯過來應(yīng)該是“重新打開”,但是總覺得不順,所以就譯成擴(kuò)展了,如果有不妥請指正。

當(dāng)你想擴(kuò)展一個類你可以直接使用reopen()方法為一個已經(jīng)定義好的類添加屬性、方法。如果是使用extend()方法你需要重新定義一個子類,然后在子類中添加新的屬性、方法。 前一篇所過,調(diào)用create()方法時候不能傳入計算屬性并且不推薦在此方法中新定義、重寫方法,但是使用reopen()方法可以彌補(bǔ)create()方法的補(bǔ)足。與extend()方法非常相似,下面的代碼演示了它們的不同之處。

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();
    },
    //  新增一個計算屬性
    fullName: Ember.computed(function() {
    console.log("compute method...");
    })
});
var p = Parent.create();    
console.log("name = " + p.get('name') + ", pwd = " + p.get('pwd'));   
p.fun1();
p.fun2();    
p.common();
console.log("---------------------------");    
p.get('fullName');  //  獲取計算屬性值,這里是直接輸出:compute method...


//  使用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();

執(zhí)行結(jié)果

從執(zhí)行結(jié)果可以看到如下的差異:
同點(diǎn): 都可以用于擴(kuò)展某個類。
異點(diǎn)

  1. extend需要重新定義一個類并且要繼承被擴(kuò)展的類;
  2. reopen是在被擴(kuò)展的類本身上新增屬性、方法,可以擴(kuò)展計算屬性(相比create()方法);

到底用那個方法有實(shí)際情況而定,reopen方法會改變了原類的行為(可以想象為修改了對象的原型對象的方法和屬性),就如演示實(shí)例一樣在reopen方法之后調(diào)用的Child2類的common方法的行為已經(jīng)改改變了,在編碼過程忘記之前已經(jīng)調(diào)用過reopen方法就有可能出現(xiàn)自己都不知道怎么回事的問題! 如果是extend方法會導(dǎo)致類越來越多,繼承樹也會越來越深,對性能、調(diào)試也是一大挑戰(zhàn),但是extend不會改變被繼承類的行為。

擴(kuò)展靜態(tài)屬性

使用reopenClass()方法可以擴(kuò)展static類型的屬性、方法。

Parent = Ember.Object.extend();   

    
//  使用reopenClass()方法添加新的static屬性、方法
Parent.reopenClass({
    isPerson: true,
    username: 'blog.ddlisting.com' 
    //,name: 'test'  //這里有點(diǎn)奇怪,不知道為何不能使用名稱為name定義屬性,會提示這個是自讀屬性,使用username卻沒問題??!估計name是這個方法的保留關(guān)鍵字
});


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方法中使用屬性name的問題下面的地址有解釋

  1. http://discuss.emberjs.com/t/reopenclass-method-can-not-pass-attribute-named-name-of-it/10189
  2. http://stackoverflow.com/questions/36078464/reopenclass-method-can-not-pass-attribute-named-name-of-it

博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。绻阌X得博文對你有點(diǎn)用在github項目上給我個star吧。您的肯定對我來說是最大的動力?。?/p>

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號