當前位置:才華齋>設計>網頁設計>

關於JavaScript中的類Class詳細介紹

網頁設計 閱讀(7.85K)

在JavaScript中,可以使用類(Class)來實現面向物件程式設計(Object Oriented Programming)。不過,JavaScript中的類與Java中的有所不同,其相應的定義和使用也不一樣。

關於JavaScript中的類Class詳細介紹

JavaScript中類的定義

在JavaScript中,所有從同一個原型物件(prototype)處衍生出來的物件組成了一個類;也就是說,JavaScript中的類是一個物件集合的概念,如果兩個物件它們的prototype相同,那麼它們就屬於同一個類;JavaScript中的類甚至都不需要類名。以下面的程式碼為例:

複製程式碼 程式碼如下:

var p = {x:42};

var a = te(p);

var b = te(p);

(a === b);//false

(rototypeOf(a) === rototypeOf(b));//true

在上述例子中,物件a和b擁有相同的原型物件(prototype) p,因此a和b屬於同一個類(雖然這個類都沒有類名),它們從原型物件p處繼承了值為42的屬性x。

從這個例子中可以看到,原型物件的作用就相當於模板,可以由之衍生/創建出多個物件,其地位與Java語言中的類程式碼(Class code)相同,是JavaScript中類定義的核心。以下這個例子中的原型物件就呈現出更像類程式碼的樣子:

複製程式碼 程式碼如下:

var p = {

INCREMENT_BY : 1,

increment : function(x){

return x + EMENT_BY;

}

}

var a = te(p);

var b = te(p);

(ement(7));//8

(ement(9));//10

上述例子中,原型物件p定義了一個值為1的`property (INCREMENT_BY)和一個名為increment的函式;物件a和b從p這個模板處獲取了INCREMENT_BY和increment函式。當呼叫物件a或b的increment函式時,JavaScript會試圖獲取a或b的INCREMENT_BY值(EMENT_BY);由於INCREMENT_BY是從p中獲取的,因此其值都是1 — 從模板中獲取的,值都相同的變數,類似於Java中的靜態類變數(static variable),因此上面的例子中對INCREMENT_BY變數命名時使用了全大寫字元。

在上面的例子中,所有從模板p處創建出來的物件(屬於同一個類的這些物件),其屬性和行為都是一模一樣的。但實際上對於同一個類的不同物件,它們除了擁有類所定義的屬性/行為以外,往往具有一些自身所特有的屬性與行為。因此,如果需要將prototype這個模板當作類來使用的話,就必須對每一個從中衍生出來的物件進行一定的定製:

複製程式碼 程式碼如下:

var p = {

INCREMENT_BY : 1,

increment : function(x){

return x + EMENT_BY + om_increment_by;

}

}

var a = te(p);

var b = te(p);

om_increment_by = 0;

om_increment_by = 1;

(ement(7));//8

(ement(9));//11

在這個例子中,從模板p處創建出來的物件a和b擁有一個彼此間值不一定相等的變數custom_increment_by,而它們的increment()函式這個行為的最終結果則與custom_increment_by的值相關。一般來說,對新建物件進行定製化的工作往往放在統一的函式中進行:

複製程式碼 程式碼如下:

var p = {

INCREMENT_BY : 1,

increment : function(x){

return x + EMENT_BY + om_increment_by;

}

}

function getIncrementalClassObject(customIncrementByValue){

var incrementalObj = te(p);

om_increment_by = customIncrementByValue;

return incrementalObj;

}

var a = getIncrementalClassObject(0);

var b = getIncrementalClassObject(1);

(ement(7));//8

(ement(9));//11

如此,便通過原型物件p和getIncrementalClassObject()函式完成了一個類的定義:可以通過呼叫getIncrementalClassObject()函式來獲取原型物件都是p的物件,而在呼叫getIncrementalClassObject()函式過程中可以對這些新建物件進行一定的定製化。值得注意的是,此時這個已經定義了的類還沒有類名,為了方便描述,姑且稱之為Incremental。

回顧getIncrementalClassObject()函式中所做的工作,可以看到從Incremental這個類中建立新的物件所經歷的過程如下:

1.建立一個空物件,並將其原型物件定義為p。

2.根據不同的引數值,對這個新建的空物件進行定製。

3.返回已經定製完成的新物件。

在JavaScript中,可以通過使用Constructor(建構函式)來快速地完成類的定義以及新物件的建立。

JavaScript中的Constructor(建構函式)

從上述Incremental類這個例子中可以看到,定義新的類需要兩部分程式碼:建立原型物件作為模板、建立自定義函式對新物件進行初始化;而從類中建立新的物件則經歷了三個過程:指定新物件的原型物件、定製/初始化新物件、返回這個新物件。在JavaScript中,這一切都可以通過Constructor(建構函式)來完成。

JavaScript中的Constructor是一個函式(function),承擔對新物件進行初始化的職責;而這個Constructor函式的prototype則作為模板用於建立新物件。仍以上述Incremental類為例,用Constructor來重寫程式碼後是這樣的:

複製程式碼 程式碼如下:

function Incremental(customIncrementByValue){

om_increment_by = customIncrementByValue;

}

otype = {

INCREMENT_BY : 1,

increment : function(x){

return x + EMENT_BY + om_increment_by;

}

}

var a = new Incremental(0);

var b = new Incremental(1);

(ement(7));//8

(ement(9));//11

通過new關鍵詞,使用Constructor函式來建立新物件這一過程,其實際上經歷了以下幾個階段:

建立一個新的空物件。

1.將這個物件的原型物件指向constructor函式的prototype屬性。

2.將這個物件作為this引數,執行constructor函式。

3.這與之前的getIncrementalClassObject()函式中所做的工作是一樣的。

類名

在使用Constructor建立物件時,相應的物件也就有了“類名”,這可以從instanceof操作符的結果上得到驗證:

複製程式碼 程式碼如下:

(a instanceof Incremental);//true

(b instanceof Incremental);//true

不過,instanceof操作符並不判斷物件是否由Incremental這一建構函式所建立,instanceof操作符只判斷物件的原型物件是否為otype。當存在兩個prototype一樣的建構函式時,instanceof操作符將統一返回true,而不會區分用於建立物件的建構函式到底是哪個。

複製程式碼 程式碼如下:

function Incremental2(customIncrementByValue){

om_increment_by = customIncrementByValue + 3;

}

otype = otype;

(a instanceof Incremental2);//true