JavaScript基於面向對象之創建對象(一)

連接:http://blog.csdn.net/erlian1992/article/details/50211229

   這一次我們深入的學習一下JavaScript面向對象技術,在學習之前,必要的說明一下一些面向對象的一些術語。

這也是所有面對對象語言所擁有的共同點。有這樣幾個面向對象術語:

       對象

       ECMA-262把對象(object)定義爲“屬性的無序集合,每個屬性存放一個原始值、對象或函數”。嚴格來說,這意味

着對象是無特定順序的值的數組。儘管ECMAScript如此定義對象,但它更通用的定義是基於代碼的名詞(人、地點或

事物)的表示。

       類

       每個對象都由類定義,可以把類看做對象的配方。類不僅要定義對象的接口(interface)(開發者訪問的屬性和方

法),還要定義對象的內部工作(使屬性和方法發揮作用的代碼)。編譯器和解釋程序都根據類的說明構建對象。

       實例

       程序使用類創建對象時,生成的對象叫作類的實例(instance)。對類生成的對象的個數的唯一限制來自於運行

代碼的機器的物理內存。每個實例的行爲相同,但實例處理一組獨立的數據。由類創建對象實例的過程叫做實例化

(instantiation)。

       在前面的章節我們提到過,ECMAScript並沒有正式的類。相反,ECMA-262把對象定義描述爲對象的配方。這

是 ECMAScript邏輯上的一種折中方案,因爲對象定義實際上是對象自身。即使類並不真正存在,我們也把對象定義

叫做類,因爲大多數開發者對此術語更熟悉,而且從功能上說,兩者是等價的。

       使用預定義對象只是面嚮對象語言的能力的一部分,它真正強大之處在於能夠創建自己專用的對象。

ECMAScript 擁有很多創建對象的方法。

       一原始方式

       因爲對象的屬性可以在對象創建後動態定義,所有許多開發者都在JavaScript 最初引入時編寫類似下面的代碼:

[javascript] view plaincopyprint?
  1. var Car = new Object();  
  2. Car.color = "blue";  
  3. Car.doors = 4;  
  4. Car.mpg = 25;  
  5. Car.showColor = function() {  
  6.     return this.color;  
  7. };  
  8. document.write(Car.showColor());//輸出:blue  

       在上面的代碼中,創建對象Car。然後給它設置幾個屬性:它的顏色是藍色,有四個門,每加侖油可以跑 25 英

裏。最後一個屬性實際上是指向函數的指針,意味着該屬性是個方法。執行這段代碼後,就可以使用對象Car。不過

這裏有一個問題,就是可能需要創建多個Car的實例,這樣就造成了我們會重複許多類似的代碼,這樣會很麻煩。

       二工廠方式

       要解上述的多個類似對象聲明的問題,開發者創造了能創建並返回特定類型的對象的工廠方式。這種方式就是爲

瞭解決實例化對象產生大量重複的問題。

       (1)無參數的工廠方式

       例如,函數createCar()可用於封裝前面列出的創建Car對象的操作:

[javascript] view plaincopyprint?
  1. function createCar() {  
  2. var TempCar = new Object();  
  3. TempCar.color = "blue";  
  4. TempCar.doors = 4;  
  5. TempCar.mpg = 25;  
  6. TempCar.showColor = function() {  
  7.        return this.color;  
  8.   };  
  9.   return TempCar;  
  10. };  
  11. var Car1 = createCar();  
  12. var Car2 = createCar();  
  13. document.write(Car1.showColor()+"<br/>");//輸出:blue  
  14. document.write(Car2.showColor());//輸出:blue  

       在這裏,第一個例子中的所有代碼都包含在createCar()函數中。此外,還有一行額外的代碼,返回TempCar 對

象作爲函數值。調用此函數,將創建新對象,並賦予它所有必要的屬性,複製出一個我們在前面說明過的Car對象。

因此,通過這種方法,我們可以很容易地創建Car對象的兩個版本(Car1和 Car2),它們的屬性完全一樣。

       (2)有參數的工廠方式

       我們還可以修改createCar()函數,給它傳遞各個屬性的默認值,而不是簡單地賦予屬性默認值:

[javascript] view plaincopyprint?
  1. function createCar(Color,Doors,Mpg) {  
  2.   var TempCar = new Object();  
  3.   TempCar.color = Color;  
  4.   TempCar.doors = Doors;  
  5.   TempCar.mpg = Mpg;  
  6.   TempCar.showColor = function() {  
  7.        return this.color;  
  8.   };  
  9.   return TempCar;  
  10. };  
  11. var Car1 = createCar("red",4,23);  
  12. var Car2 = createCar("blue",3,25);  
  13. document.write(Car1.showColor()+"<br/>");//輸出:red  
  14. document.write(Car2.showColor());//輸出:blue  

       給createCar()函數加上參數,即可爲要創建的Car對象的color、doors 和mpg屬性賦值。這使兩個對象具有相同

的屬性,卻有不同的屬性值。

       工廠方式解決了重複實例化的問題,但是還是有一個問題,那就是前面的例子中,每次調用函數createCar(),都

要創建新函數showColor(),意味着每個對象都有自己的 showColor() 版本。而事實上,每個對象都共享同一個函數。

有些開發者在工廠函數外定義對象的方法,然後通過屬性指向該方法,從而避免這個問題:

[javascript] view plaincopyprint?
  1. function showColor() {  
  2.      return this.color;  
  3. };  
  4. function createCar(Color,Doors,Mpg) {  
  5.   var TempCar = new Object();  
  6.   TempCar.color = Color;  
  7.   TempCar.doors = Doors;  
  8.   TempCar.mpg = Mpg;  
  9.   TempCar.showColor = showColor;  
  10.   return TempCar;  
  11. };  
  12. var Car1 = createCar("red",4,23);  
  13. var Car2 = createCar("blue",3,25);  
  14. document.write(Car1.showColor()+"<br/>");//輸出:red  
  15. document.write(Car2.showColor());//輸出:blue  

       在上面這段重寫的代碼中,在函數 createCar()之前定義了函數 showColor()。在createCar()內部,賦予對象一個

指向已經存在的 showColor() 函數的指針。從功能上講,這樣解決了重複創建函數對象的問題;但是從語義上講,該

函數不太像是對象的方法。所有這些問題都引發了開發者定義的構造函數的出現。

       三構造函數方式

       創建構造函數就像創建工廠方式的函數一樣容易。第一步選擇構造函數的名字。根據慣例,這個名字的首字母大

寫,以使它與首字母通常是小寫的變量名分開。除了這點不同,構造函數看起來很像工廠方式的函數。請看下面的例

子:

[javascript] view plaincopyprint?
  1. function Car(Color,Doors,Mpg) {  
  2.   this.color = Color;  
  3.   this.doors = Doors;  
  4.   this.mpg = Mpg;  
  5.   this.showColor = function() {  
  6.        return this.color;  
  7.   };  
  8. };  
  9. var Car1 = new Car("red",4,23);  
  10. var Car2 = new Car("blue",3,25);  
  11. document.write(Car1.showColor()+"<br/>");//輸出:red  
  12. document.write(Car2.showColor());//輸出:blue  

       下面爲您解釋上面的代碼與工廠方式的差別。首先在構造函數內沒有創建對象,而是使用this關鍵字。使用new運

算符構造函數時,在執行第一行代碼前先創建一個對象,只有用this才能訪問該對象。然後可以直接賦予this屬性,默

認情況下是構造函數的返回值(不必明確使用 return 運算符)。現在,用new運算符和對象名Car創建對象,就更像

 ECMAScript 中一般對象的創建方式了。

      就像工廠方式的函數,構造函數會重複生成函數,爲每個對象都創建獨立的函數版本。不過,與工廠方式的函數

相似,也可以用外部函數重寫構造函數,同樣地,這麼做語義上無任何意義。這正是下面要講的原型方式的優勢所

在。在下篇博客會詳細的分析面向對象的原型方式以及其他綜合的方式。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章