(六)javascriptJS中定義對象的幾種方式(轉)


JavaScript學習12 JS中定義對象的幾種方式

  轉自:  http://www.cnblogs.com/mengdd/p/3697255.html

  JavaScript中沒有類的概念,只有對象。

  在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();

 

 

 

 解析: 一定要用this.getInfo = function() 這種方法來定義方法,否則person.getInfo();將無法調用person里定義好的方法。  

 

 

 

  改進版:加上參數:

復制代碼
function Person(username, password) { this.username = username; this.password = password; this.getInfo = function() { alert(this.username + ", " + this.password); } } var person = new Person("zhangsan", "123"); 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>
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM