Ember 類(lèi)的擴(kuò)展

2018-01-06 16:47 更新

擴(kuò)展一般屬性

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

當(dāng)你想擴(kuò)展一個(gè)類(lèi)你可以直接使用reopen()方法為一個(gè)已經(jīng)定義好的類(lèi)添加屬性、方法。如果是使用extend()方法你需要重新定義一個(gè)子類(lèi),然后在子類(lèi)中添加新的屬性、方法。 前一篇所過(guò),調(diào)用create()方法時(shí)候不能傳入計(jì)算屬性并且不推薦在此方法中新定義、重寫(xiě)方法,但是使用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({
    //  給類(lèi)Parent為新增一個(gè)屬性
    pwd: '12345',
    //  給類(lèi)Parent為新增一個(gè)方法
    fun2() {
        console.log("The pwd is " + this.pwd);
    },
    //    重寫(xiě)父類(lèi)的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({
    //  給類(lèi)Parent為新增一個(gè)屬性
    pwd: '12345',
    //  給類(lèi)Parent為新增一個(gè)方法
    fun2() {
        console.log("The pwd is " + this.pwd);
    },
    //  重寫(xiě)類(lèi)本身common()方法
    common() {
        console.log("override common method by reopen method...");
        //this._super();
    },
    //  新增一個(gè)計(jì)算屬性
    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');  //  獲取計(jì)算屬性值,這里是直接輸出:compute method...


//  使用extend()方法添加新的屬性、方法
Child2 = Parent.extend({
    //  給類(lèi)Parent為新增一個(gè)屬性
    pwd: '12345',
    //  給類(lèi)Parent為新增一個(gè)方法
    fun2() {
        console.log("The pwd is " + this.pwd);
    },
    //    重寫(xiě)父類(lèi)的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ò)展某個(gè)類(lèi)。
異點(diǎn)

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

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

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

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

Parent = Ember.Object.extend();   

    
//  使用reopenClass()方法添加新的static屬性、方法
Parent.reopenClass({
    isPerson: true,
    username: 'blog.ddlisting.com' 
    //,name: 'test'  //這里有點(diǎn)奇怪,不知道為何不能使用名稱(chēng)為name定義屬性,會(huì)提示這個(gè)是自讀屬性,使用username卻沒(méi)問(wèn)題?。」烙?jì)name是這個(gè)方法的保留關(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

對(duì)于在reopenClass方法中使用屬性name的問(wèn)題下面的地址有解釋

  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)過(guò)多次修改,博文上的代碼與github代碼可能又出入,不過(guò)影響不大?。?,如果你覺(jué)得博文對(duì)你有點(diǎn)用在github項(xiàng)目上給我個(gè)star吧。您的肯定對(duì)我來(lái)說(shuō)是最大的動(dòng)力?。?/p>

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)