天天看點

javascript中建立對象的幾種方式

javascript中提供了通過Object構造函數或對象字面量方式來建立單個的對象,當我們想要建立很多對象的時候,簡單的通過這兩種方法就會産生大量的重複。在此,我總結了幾種建立對象的模式。本文是在我閱讀《javascript進階程式設計》後總結而來。

這種模式通過用函數來減少代碼重複,利用函數的參數作為接口,與對象的屬性與方法對接。

這樣就完成了簡單的代碼複用,實作了代碼重複,但是無法确定所建立對象的類型。

我們都知道Object,Array等原生的構造函數可以用來建立對象。構造函數模式和此類似,通過自定義建立構造函數,來建立新類型的對象。

按照慣例,構造函數應以一個大寫字母開頭。這種模式可以将新對象的類型确定下來。然後這種模式依舊存在問題,test1和test2兩個執行個體中都有

sayname方法,在javascript中函數就是對象,是以在建立test1和test2的同時也執行個體化了兩次函數對象,相當于這樣:

上面這種方法通過将屬性和方法添加到了構造函數的原型對象中,這樣新對象的所有執行個體會共享這些屬性和方法。

為了進一步減少代碼量,有人提出了重寫原型對象的方法。看下面的例子。

這種方法通過重寫原型對象進一步減少代碼重複,然而這樣的寫法帶來了新的問題。

在簡單的通過原型模式建立對象時,原型對象的動态變化會實時的反應

在執行個體中,因為執行個體中的[[Prototype]]屬性是指向原型對象的,這樣對于調用屬性和方法的向上搜尋過程,會搜尋到原型對象中的屬性和方法。而當

先執行個體化一個對象後,再重寫原型對象,執行個體中的[[Prototype]]不再指向新的原型對象,因而導緻在調用的過程中無法向上搜尋到新的原型對象,所

以在使用重寫原型對象方法的時候,一定要先重寫對象,再建立執行個體。

原型對象模式依舊存在缺點,雖然它省略了為函數傳參這一環節,但是執行個體預設情況下都取得相同的屬性值。此外對于包含引用類型的屬性來說,當對執行個體屬性修改會導緻原型對象中屬性的同步變化。這樣,這種變化也就實時的反應在了所有的執行個體中。顯然這不是我們想要的結果。

聯系前面說的構造函數模式,我們可以通過組合使用構造函數模式和原型模式來解決這一問題。

在構造函數中定義執行個體屬性,在原型模式中定義方法和共享的屬性。這樣,每個執行個體都有自己的執行個體屬性的副本,同時也有共享的屬性和方法,節省了記憶體,也可以通過傳參來定義執行個體屬性。

動态原型模式其實相當于原型模式的一個變種,将所有的資訊都封裝在構造函數中,僅在必要的情況下初始化原型對象。

在這個構造函數中通過判斷屬性是否存在來決定是否對原型對象初始化。這樣隻有在第一次執行個體化對象時才會對原型對象初始化,可以說是十分的完美了。

當我們想為一個已經存在的構造函數建立一個具有額外方法的構造函數,由于不能重寫存在的構造函數,這時就可以使用這種模式了。看例子。

這個例子中,建立了一個具有額外方法的數組,具有額外的特殊方法,在不修改數組構造函數的前提下,建立了一個新的構造函數。不過寄生構造函數模式傳回的對象與構造函數的原型對象沒有關系。

以上為我總結的建立對象的幾種方法,還有一種穩妥構造函數模式,适用于安全環境中,在此就不做介紹了。

以上内容均為閱讀《javascript進階程式設計》總結而來。