【JavaScript學習】JavaScript物件建立

一點心青發表於2013-07-25

1.最簡單的方法,建立一個物件,然後新增屬性

 1 var person = new Object();
 2 person.age = 23;
 3 person.name = "David";
 4 person.job = "student";
 5 person.sayName = function ()
 6 {
 7        alert(this.name);
 8 };
 9 
10 //類似於定義鍵值對或者json資料格式的定義方法.
11 var person =
12 {
13      age:23,
14      name:"David",
15      job:"student",
16      sayName:function()
17      {
18          alert(this.name);
19      }
20 };

該方法簡單明瞭,缺點就是當要建立多個同型別的物件時,重複性的程式碼較多.

2.解決方法1中的問題,借鑑許多軟體設計的思想,引入工廠模式,即構造一個建立物件的工廠函式,實現物件建立的功能.

 1 function createPerson(name,age,job)
 2 {
 3        var o = new Object();
 4        o.name = name;
 5        o.age = age;
 6        o.job = job;
 7        o.sayName = function()
 8        {
 9                alert(this.name);
10        };
11        return o;
12 }
13 var person = createPerson("David",23,"student");

該方法解決了程式碼重複的問題,可以利工廠函式建立出多個物件.但此方法返回的物件都是Object型別,不能標識建立的物件的型別屬性.

3.建構函式模式,建立建構函式,結合new操作符可以建立物件

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6     this.sayName = function()
 7     {
 8         alert(this.name);
 9     }
10 }
11 var person1 = new Person("David",23,"student");
12 var person2 = Person("Bill",21,"Boss");
13 person1.sayName();  //顯示David
14 person2.sayName(); //顯示undefined
15 sayName();          //顯示Bill

person1 結合new 操作建立了一個物件例項,但person2沒有結合new,直接呼叫Person(name,age,job)函式,此時,函式的作用域裡的this指的是window,因而出現後兩行的顯不結果.安全的建構函式可以避免出現上述的問題

 1 function Person(name,age,job)
 2 {
 3      if(this instanceof Person)
 4      {
 5           this.name = name;
 6           this.age = age;
 7           this.job = job;
 8           this.sayName = function()
 9           {
10               alert(this.name);
11           }
12      }
13      else
14          return new Person(name,age,job);
15 }

this instanceof Person  檢測當前this是否指向到Person物件. 這樣改進後,將不會出上面描述的問題.關鍵是理解this是指向當前執行環境的,關於函式的執行環境以及作用域鏈,以後再作介紹.一般型別的方法是一樣的,可以共享,但使用該方法,每建立一個物件,都會建立一個方法的副本,產生程式碼的重複性.

4.解決該問題,可以把方法置於建構函式體外定義,建構函式內只需要引用在建構函式外定義的函式即可.

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6     this.sayName = sayName;
 7 }
 8 
 9 function sayName()
10 {
11     alert(this.name);
12 }

這樣可以解決方法共享的問題,但會引入其他問題,這樣將導致global scope裡將會有許有方法,使用global scope過於龐大,這樣不便於程式碼管理,方法和相應的屬性分開.

5.原型模式.

 1 function Person(){}
 2 Person.prototype.name = "David";
 3 Person.prototype.age = 23;
 4 Person.prototype.job = "student";
 5 Person.prototype.sayName = function()
 6 {  
 7     alert(this.name);
 8 };
 9 var person1 = new Person();
10 var person2 = new Person();

通過設定建構函式的原型,來達到物件中屬性和方法的共享,person1和person2中對應的屬性和方法都是一樣的. 雖然這種方法,實現了程式碼共享,減少了程式碼的重複,但並不符合人們的需求,一般都是需要各個物件既有共享的方法和屬性,又有各自的特點和屬性.而且這種方法不能傳遞初始化引數,預設構造的物件都具有與原型相同的屬性.

6.原型和建構函式混合模式  利用原型來設定方法,達到方法的共享,利用建構函式來實現屬性的設定,支援初始化引數傳遞,達到屬性的個性化

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6 }
 7 Person.prototype = {
 8     constructor:Person,
 9     sayName:function()
10     {
11         alert(this.name);
12     }
13 };
14 var person1 = new Person("David",23,"student");
15 var person2 = new Person("Bill",21,"Boss");

這樣person1和person2對應的屬性不共享,但方法sayName共享.該方法基本可以滿足一般使用者建立物件的需求.該方法存在一點不好,就是方法和屬性要分開設定,而且在利用原型設定方法時,若是重寫原型,則必須指定constructor為建構函式,若是隻設定相應的屬性,如Person.prototype.sayName = function(){};則不需要指定constructor屬性.

7.動態原型模式 可以將屬性和方法設定一起置於建構函式內.

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6   
 7   if(typeof this.sayName != "function")
 8     {
 9          Person.prototype.sayName = function()
10          {
11              alert(this.name);
12          };
13     }
14  }

檢測this.sayName是否已經定義,若定義了,則不用設定原型.否則,設定原型定義sayName函式.這種方法同樣可以達到屬性個性化,方法共享的要求

       總結,以上就是幾種關於物件建立的方法的總結,逐步完善,從每種方法存在的問題出發,從而尋找更好的解決方法,這樣可以進一步的理解javascript中各種機制設計的最初目的.

 

相關文章