2015年10月24日 星期六

dojo Creating Classes

dojo Creating Classes

簡介

雖說在 Javascript 用的是 prototyping 的繼承模式,並沒有其它物件導向程式語言中所謂「類別」(Class)的概念,在 Javascript 中只有「物件」(Object) 的存在,而且物件可以繼承另一個物件。但 dojo 在 Javascript 的基礎上還是實作了類似「類別」的概念。dojo/_base/declare 這個模組就是 dojo 中用來宣告一個類別的函式。在 dojo 中,物件可以多重繼承 (Multiple Inheritance)。在實務上,宣告類別時,多半會寫成模組,以單獨的檔案形式存在,但此篇只先討論在 dojo 中類別的宣告方式。

declare 的語法如下:

declare(classId, superClasses, mixin)

declare() 函式有三個參數,分別說明如下:

    classId
    為選項,可以不給,不給時該類別稱為「匿名類別」(Anonymous Class)。給予時,需給予包含命名空間(namesapce) 的類別名,整個名稱會是一個全域變數,格式為 "namespace/ClassId"。配合物件導向程式語言的一般命名規則,類別名稱的第一個字母會大寫。
    superClasses
    賦予值可以是 null 、一個類別名或是一個類別名陣列。賦予值為 null 時,表示此類別沒有任何要繼承的其它類別。賦於值為單一類別名時,表示此類別僅有一個父類別需要繼承。賦予值為一類別名陣列時,表示多重繼承,此類別會繼承陣列中所有的類別。此時要特別注意陣列中類別名在陣列中的前後次序,陣列中的第一個類別稱為基礎類別 (base class),由此類別依序將後繼類別的屬性和函式融入 (mixin),意味著當前類別和後繼類別具有相同屬性名或函式名時,後繼的屬性值和函式會取代先前類別的屬性值或函式。
    mixin
    最終的參數則是一個物件,此物件具有該物件特有的屬性及函式。同樣的,若繼承類別中的屬性名或函式名與此參數所提供的屬性名或函式相同時,則此參數中的屬性值和函式會取代繼承類別中的屬性值和函式。

mixin 中有個很特殊的函式叫 constructor(),這個函式就是物件的建構子。在每次用 new 這個操作子以建構一個新物件時,這個函式都會被呼叫一次。因此,這個函式通常都會將傳遞進來的參數,用來初始化 (initialize) 建構的物件。同時,這個函式會先行呼叫父類別的 constructor() 函式,並傳入參數,以初始化父類別的屬性;之後,再初始化本身的屬性。

另一個很特殊的函式是 this.inherited(arguments),用來呼叫父類別中的函式。語法如下:

inherited(methodId, arguments, [arg1, arg2,...]);
    methodId
    指定要呼叫父類別函式的名稱,如果從缺,則呼叫父類別中與呼叫 inherited() 函式相同名稱的函式,如果呼叫 inherited() 的函式沒有明確的函式名稱,例如「匿名函式」時,則須明確指定 methodId 的值。
    arguments
    Javascript 中的保留字,是一個含有全部傳入參數的陣列。
    [arg1, arg2,...]
    以此陣列成為呼叫父類別函式時的參數。從缺時,則傳入 arguments。


declare("Person",null, {
    name = "John"
});

var Person = declare(null, {
    name = "John"
});

以上兩種寫法都會產生一個名為 Person 的類別。

Script


第 9~15 行建構一個名為 "Person" 的類別。
第 17 行則建立一個類別變數 (class variable),計算由此類別所建構的物件數。
第 19~25 行建構一個名為 "Employee" 繼承 "Person" 的類別,加入 salary 屬性。
第 28~32 行建構一個名為 "Boss" 繼承 "Employee" 的類別,並修改 askForRaise() 函式,在函式中呼叫 "Employee" 的 askForRaise() 函式,取得傳回值後,再乘 2 。

沒有留言:

張貼留言