09.09 JavaScript七種非常經典的創建對象方式

JavaScript創建對象的方式有很多,通過Object構造函數或對象字面量的方式也可以創建單個對象,顯然這兩種方式會產生大量的重複代碼,並不適合量產。接下來介紹七種非常經典的創建對象的方式,他們也各有優缺點。

一、工廠模式可以無數次調用這個工廠函數,每次都會返回一個包含兩個屬性和一個方法的對象。工廠模式雖然解決了創建多個相似對象的問題,但是沒有解決對象識別問題,即不能知道一個對象的類型。

JavaScript七種非常經典的創建對象方式

二、構造函數模式沒有顯示的創建對象,使用new來調用這個構造函數,使用new後會自動執行如下操作:①創建一個新對象;②將構造函數的作用域賦給新對象(因此this就指向了這個新對象);③執行構造函數中的代碼(為這個新對象添加屬性);④返回新對象。

JavaScript七種非常經典的創建對象方式

缺點:每個方法都要在每個實例上重新創建一遍。創建兩個完成同樣任務的的Function實例的確沒有必要。況且有this對象在,根本不用在執行代碼前就把函數綁定到特定的對象上,可以通過這樣的形式定義:

JavaScript七種非常經典的創建對象方式

如此一來,就可以將sayName()函數的定義轉移到構造函數外部。而在構造函數內部,我們將sayName屬性設置成全局的sayName函數。這樣的話,由於sayName包含的是一個指向函數的指針,因此person1和person2對象就可以共享在全局作用域中定義的同一個sayName()函數。這樣做解決了兩個函數做同一件事的問題,但是新的問題又來了:在全局作用域中定義的函數實際上只能被某個對象調用,這讓全局作用域有點名不副實。而更重要的是:如果對象需要定義很多方法,那麼就需要定義很多個全局函數,這樣一來,我們自定義的這個引用類型就毫無封裝性可言了。

三、原型模式將信息直接添加到原型對象上。使用原型的好處是可以讓所有的實例對象共享它所包含的屬性和方法,不必在構造函數中定義對象實例信息,而是可以將這些信息直接添加到原型對象中。

JavaScript七種非常經典的創建對象方式

①理解原型無論什麼時候,只要創建了一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性。在默認情況下,所有prototype屬性都會自動獲得一個

constructor(構造函數)屬性,這個屬性包含一個指向prototype屬性所在函數的指針。每當代碼讀取某個對象的某個屬性時,都會執行一搜索,目標是具有給定名字的屬性。搜索首先從對象實例本身開始。如果在實例中找到了具有給定名字的屬性,則返回該屬性的值;如果沒有找到,則繼續搜索指針指向的原型對象,在原型對象中查找具有給定名字的屬性。如果在原型對象中找到了這個屬性,則返回該屬性的值。雖然可以通過對象實例訪問保存在原型中的值,但卻不能通過對象實例重寫原型中的值。如果我們在實例中添加了一個屬性,而該屬性與實例中的一個屬性同名,那麼就會在實例中創建該屬性,該屬性將會屏蔽原型中的那個屬性。即使是將屬性設置為null,也只是在實例中的屬性值為null。不過,使用delete操作符可以完全刪除實例屬性,從而能夠重新訪問原型中的屬性。使用hasOwnProperty() 方法可以檢測一個屬性是存在於實例中,還是存在與原型中。這個方法只在給定屬性存在於對象實例中時,才會返回true。

②原型與in操作符in操作符會在通過對象能夠訪問給定屬性時返回true,無論該屬性是存在於實例中還是原型中。③更簡單的原型語法

JavaScript七種非常經典的創建對象方式

在上面的代碼中,將Person.prototype設置為等於一個以對象字面量形式創建的新對象。最終結果相同,但有一個例外:constructor屬性不再指向Person。

四、組合使用構造函數模式和原型模式是使用最為廣泛、認同度最高的一種創建自定義類型的方法。它可以解決上面那些模式的缺點,使用此模式可以讓每個實例都會有自己的一份實例屬性副本,但同時又共享著對方法的引用,這樣的話,即使實例屬性修改引用類型的值,也不會影響其他實例的屬性值了。還支持向構造函數傳遞參數,可謂是集兩種模式的優點。

JavaScript七種非常經典的創建對象方式

五、動態原型模式將所有信息都封裝在了構造函數中,初始化的時候。可以通過檢測某個應該存在的方法是否有效,來決定是否需要初始化原型。

JavaScript七種非常經典的創建對象方式

只有在sayName方法不存在的時候,才會將它添加到原型中。這段代碼只會初次調用構造函數的時候才會執行。此後原型已經完成初始化,不需要在做什麼修改了,這裡對原型所做的修改,能夠立即在所有實例中得到反映。其次,if語句檢查的可以是初始化之後應該存在的任何屬性或方法,所以不必用一大堆的if語句檢查每一個屬性和方法,只要檢查一個就行。

六、寄生構造函數模式的基本思想就是創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然後再返回新建的對象除了使用new操作符並把使用的包裝函數叫做構造函數之外,和工廠模式幾乎一樣。構造函數如果不返回對象,默認也會返回一個新的對象,通過在構造函數的末尾添加一個return語句,可以重寫調用構造函數時返回的值。

JavaScript七種非常經典的創建對象方式

七、穩妥構造函數模式首先明白穩妥對象指的是沒有公共屬性,而且其方法也不引用this。穩妥對象最適合在一些安全環境中(這些環境會禁止使用this和new),或防止數據被其他應用程序改動時使用。穩妥構造函數模式和寄生模式類似,有兩點不同:1.是創建對象的實例方法不引用this;2.不使用new操作符調用構造函數

JavaScript七種非常經典的創建對象方式

跟寄生構造函數模式一樣,這樣創建出來的對象與構造函數之間沒有什麼關係,instanceof操作符對他們沒有意義。


分享到:


相關文章: