在上一篇文章中我們介紹了JavaScript簡單物件的建立方法,簡單js物件的最大問題是由於沒有類別的約束,無法實現物件的重複利用,並且沒有一種約定,在操作時會帶來問題。所以人們從設計模式中藉用了一種工廠模式來建立JavaScript物件。
使用工廠方法建立JavaScript物件
工廠方法的想法是在一個函數中建立一個對象,然後為這個物件設定對應的屬性和方法,最後將這個物件傳回。透過函數來封裝,以特定的介面建立物件。以下是一個以工廠方法創建person物件的例子:
function createPerson(name,age){ var o = new Object(); o.name = name; o.age = age; o.say = function(){ alert(this.name + "," + this.age); } return o; } // 实例化p1和p2对象 var p1 = createPerson("Leon",22); var p2 = createPerson("Ada",20); //调用p1和p2对象的say()方法 p1.say(); p2.say();
使用工廠方法雖然有效的解決了類別的問題,但是依然存在另外一個問題。我們無法偵測物件p1和p2的資料類型。我們使用typeof僅僅只能偵測出物件是一個Object類型:
console.info(typeof p1); // 控制台输出:Object
如果我們想要使用instanceof來判斷物件是一個Object類型的類型:
// 使用构造函数方式来创建Person类 function Person(name,age){ this.name = name; this.age = age; this.say = function(){ console.info(this.name + "," + this.age); } } // 通过new关键字来创建对象 var p1 = new Person("Leon",22); var p2 = new Person("Ada",20); // 调用对象的方法 p1.say(); p1.say();
如果我們想要使用instanceof來判斷物件的類型,那麼p1 instanceof ?,instanceof後面要填入什麼類型呢?我們並不知道。
使用建構函式建立JavaScript物件
由於工廠方法無法確定物件的具體類型,所以人們又提出了一種新的建立JavaScript物件的方法—建構函式方法。在JavaScript中建構函數可以用來建立特定類型的對象,例如Object和Array這些js原生建構函數,在執行時會自動出現在執行環境中。我們也可以自訂建構函數,從而定義自訂類型的屬性和方法。
使用建構函式來建立類別和基於工廠的方式來建立類別的方法相似,最大的差異是函數的名稱就是類別的名稱。通常依照程式規範的約定,類別的第一個字母大寫。使用建構函數建立類別時,在函數內部透過this關鍵字來完成屬性的定義。
console.info(p1 instanceof Person); //控制台显示:true console.info(p2 instanceof Person); //控制台显示:true
如上面的程式碼所示,在完成類別的建立之後,我們可以透過new關鍵字來實例化物件。
使用建構函數的方式很好的解決了檢測物件類型的問題,我們可以透過instanceof關鍵字來判斷物件是不是Person型別:
console.info(p1.constructor == Person); //控制台显示:true console.info(p2.constructor == Person); //控制台显示:true
另外,我們也可以透過constructor關鍵字來查看物件的建構函數是否為Person型別:
console.info(p1.constructor); console.info(p2.constructor);
或直接印出p1和p2的建構子來進行比較:
// 使用构造函数方式来创建Person类 function Person(name,age){ this.name = name; this.age = age; // 此时的类方法是一个全局方法的引用 this.say = say; } //将方法设置为全局的方法 function say(){ alert(this.name + "," + this.age); }
使用建構函式方法給我們所帶來的問題是每個物件中都會存在一個方法的拷貝,如果物件的方法很多的話,就會佔用大量的記憶體空間。
在一些高階的編譯型的物件導向程式語言(如Java)中,物件的方法是在執行時間動態在堆疊區產生的,它們不會佔用記憶體。而在Javascript中,使用建構函式方法所建立的對象,物件中的每一個方法都是類別方法的一個拷貝,如果對像中存在大量的方法,就會佔用大量的記憶體空間。
我們可以將類別的方法放到全域變數中定義,這樣可以讓類別中的方法指向同一個函數。程式碼如下:
rrreee透過將類別的方法設定為全域方法,可以解決物件中的方法佔用記憶體空間的問題,此時,透過建構函式建立的所有物件中的方法都指向同一個全域函數。
但是如果將所有的方法都設定為全域函數,這些函數都可以被window調用,此時就破壞了物件的封裝性,而且如果某個物件有大量的方法,就會導致程式碼中有大量的全域函數,這樣也不利於我們的開發。
為了解決建構函式方法有這些缺陷,我們就要使用原型來建立對象,下一篇文章我們將介紹使用原型來建立JavaScript對象。
以上就是JavaScript物件導向-使用工廠方法和建構函數方法創建物件的內容,更多相關內容請關注PHP中文網(www.php.cn)!