JS中定義對象的幾種方式
阿新 • • 發佈:2017-09-07
cnblogs turn 函數對象 屬性。 array fff 動態 pan 改進
在JavaScript中定義對象可以采用以下幾種方式:
1.基於已有對象擴充其屬性和方法
2.工廠方式
3.構造函數方式
4.原型(“prototype”)方式
5.動態原型方式
一.基於已有對象擴充其屬性和方法
<script type="text/javascript"> var object = new Object(); object.name = "zhangsan"; object.sayName = function(name) { this.name = name; alert(this.name); } object.sayName("lisi"); </script>
這種方式的弊端:這種對象的可復用性不強,如果需要使用多個對象,還需要重新擴展其屬性和方法。
二.工廠方式
function createObject() { var object = new Object(); object.username = "zhangsan"; object.password = "123"; object.get = function() { alert(this.username + ", " + this.password); }return object; } var object1 = createObject(); var object2 = createObject(); object1.get();
改進一:采用帶參數的構造方法:
function createObject(username, password) { var object = new Object(); object.username = username; object.password = password; object.get = function() { alert(this.username + ", " + this.password); } return object; } var object1 = createObject("zhangsan", "123"); object1.get();
改進二:讓多個對象共享函數對象
這樣,不用每個對象都生成一個函數對象。
function get() { alert(this.username + ", " + this.password); } //函數對象只有一份 function createObject(username, password) { var object = new Object(); object.username = username; object.password = password; object.get = get; //每一個對象的函數對象都指向同一個函數對象 return object; } var object = createObject("zhangsan", "123"); var object2 = createObject("lisi", "456"); object.get(); object2.get();
優點:讓一個函數對象被多個對象所共享,而不是每一個對象擁有一個函數對象。
缺點:對象和它的方法定義分開了,可能會造成誤解和誤用。
三.構造函數方式
構造函數的定義方法其實和普通的自定義函數相同。
function Person() { //在執行第一行代碼前,js引擎會為我們生成一個對象 this.username = "zhangsan"; this.password = "123"; this.getInfo = function() { alert(this.username + ", " + this.password); } //此處有一個隱藏的return語句,用於將之前生成的對象返回 //只有在後面用new的情況下,才會出現註釋所述的這兩點情況 } //生成對象 var person = new Person();//用了new person.getInfo();
四.原型(“prototype”)方式
例子:
function Person() { } Person.prototype.username = "zhangsan"; Person.prototype.password = "123"; Person.prototype.getInfo = function() { alert(this.username + ", " + this.password); } var person = new Person(); var person2 = new Person(); person.username = "lisi"; person.getInfo(); person2.getInfo();
使用原型存在的缺點:
1.不能傳參數;
2.有可能會導致程序錯誤。
如果使用原型方式來定義對象,那麽生成的所有對象會共享原型中的屬性,這樣一個對象改變了該屬性也會反映到其他對象當中。
單純使用原型方式定義對象無法在構造函數中為屬性賦初值,只能在對象生成後再去改變屬性值。
比如,username改為數組後:
function Person() { } Person.prototype.username = new Array(); Person.prototype.password = "123"; Person.prototype.getInfo = function() { alert(this.username + ", " + this.password); } var person = new Person(); var person2 = new Person(); person.username.push("zhangsan"); person.username.push("lisi"); person.password = "456"; person.getInfo(); //輸出:zhangsan,lisi, 456 person2.getInfo(); //輸出:zhangsan,lisi, 123 //雖然沒有對person2對象進行修改,但是它的name和person是一樣的,即為zhangsan,lisi
這是因為使用原型方式,person和person2指向的是同一個原型,即對應了同樣的屬性對象。
對於引用類型(比如數組),兩個對象指向了同一個引用,所以對一個所做的更改會影響另一個。
而對於字符串(字面常量值),重新賦值之後就指向了另一個引用,所以二者的修改互不影響。
對原型方式的改進:
使用原型+構造函數方式來定義對象,對象之間的屬性互不幹擾,各個對象間共享同一個方法。
<script type="text/javascript"> //使用原型+構造函數方式來定義對象 function Person() { this.username = new Array(); this.password = "123"; } Person.prototype.getInfo = function() { alert(this.username + ", " + this.password); } var p = new Person(); var p2 = new Person(); p.username.push("zhangsan"); p2.username.push("lisi"); p.getInfo(); p2.getInfo(); </script>
五.動態原型方式
在構造函數中通過標誌量讓所有對象共享一個方法,而每個對象擁有自己的屬性。
<script type="text/javascript"> function Person() { this.username = "zhangsan"; this.password = "123"; if(typeof Person.flag == "undefined") { //此塊代碼應該只在第一次調用的時候執行 alert("invoked"); Person.prototype.getInfo = function() { //這個方法定義在原型中,會被每一個對象所共同擁有 alert(this.username + ", " + this.password); } Person.flag = true;//第一次定義完之後,之後的對象就不需要再進來這塊代碼了 } } var p = new Person(); var p2 = new Person(); p.getInfo(); p2.getInfo(); </script>
JS中定義對象的幾種方式