天天看點

JavaScript基礎之建立對象的方法

  ECMA-262把對象定義為:“無序屬性的集合,其屬性可以包含基本值、對象或者函數。”嚴格來講,這就相當于說對象是一組沒有特定順序的值。對象的每個屬性或者方法都有一個名字,而每個名字都映射到一個值。正因為這樣,我們可以把ECMAScript的對象想像成散清單:無非就是一組名值對,其中值可以是資料或函數。

   建立對象的方式多種多樣,了解和掌握每種建立對象的方法對于學會JavaScript這門語言是十分重要的。

  一、使用Object構造函數

  上面的例子建立了一個名為person的對象,并給它添加了三個屬性(name,age,sex)和一個方法(sayName())。

  二、使用字面量建立對象

使用字面量建立對象的方式跟上面使用Object構造函數建立對象的方式差不多,就像開學的時候報名一樣,每來一個同學都要寫一遍姓名、年齡、性别這幾個字,很明顯效率什麼低,因為這種方法會産生大量的重複代碼。為了解決這個問題,人們開始使用工廠模式的方式來建立對象。

  三、工廠模式

  工廠模式,顧名思義就是像工廠一樣,從流水線上出來的對象都有一樣的屬性和方法。考慮到ECMAScript中無法建立類,開發人員就發明一種函數,用函數來封裝以特定接口建立對象的細節,如下面的例子:

 工廠模式看起來解決了建立多個相似對象的問題,但卻沒有解決對象識别的問題,即怎樣知道一個對象的類型。随着JavaScript的發展,又有一個新的模式出現了。

四、構造函數模式

  我們知道,像Object和Array這樣的原生構造函數,在運作時會自動出現在執行環境中,此外,我們也可以建立自定義的構造函數,進而定義自定義對象類型的屬性和方法。舉個栗子如下:

  在這個例子中,Person函數取代了上面的createPerson()函數。我們注意到,Person()中的代碼除了與createPerson()中相同的部分外,還存在以下不同之處:

      1、沒有顯示地建立對象

      2、直接将屬性和方法賦給了this對象

      3、沒有return語句

  此外,還應該注意到函數名為Person使用的是首字母大寫P。按照慣例,構造函數始終都應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭。

  要建立Person的新執行個體,必須使用new操作符。以這種方式調用構造函數實際會經曆以下四個步驟:

      1、建立一個新對象

      2、将構造函數的作用域賦給新對象(是以this就指向了這個新對象);

      3、執行構造函數中的代碼(為這個新對象添加屬性)

      4、傳回新對象

五、原型模式

  我們建立的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以有特定類型的所有執行個體共享的屬性和方法。

 原型模式也不是沒有缺點。首先,它省略了為構造函數傳遞初始化參數這一環節,結果所有執行個體在預設情況下都将取得相同的屬性值。雖然這會在某種程度上帶來了一些不便,但還不是原型的最大問題,原型模式的最大問題是由其共享的本性所導緻的。這裡舉個例子說明:

六、組合使用構造函數模式和原型模式

  建立自定義類型的最常見方式,就是組合使用構造函數模式與原型模式。構造函數模式用于定義執行個體屬性,而原型模式用于定義方法和共享的屬性。結果,每個執行個體都會有自己的一份執行個體屬性的副本,但同時又共享着對方法的引用,最大限度地節省了記憶體。另外,這種混合模式還支援向構造函數中傳遞參數;可謂集兩種模式之長。

在這個例子中,執行個體屬性都是在構造函數中定義的,而所有執行個體共享的屬性constructor和方法sayName()則是在原型中定義的。而修改了person1.friends,并不會像上個例子中那樣影響到person2.friends。

七、動态原型模式

  這個模式的好處在于看起來更像傳統的面向對象程式設計,具有更好的封裝性,因為在構造函數裡完成了對原型建立。

除了以上其中方式之外,還有寄生構造函數模式和穩妥構造函數模式。實際上這麼多種方法中,第六種和第七種是最常用的,我們需根據實際情況使用不同的方法,做到随機應變才能更加高效率的工作。

繼續閱讀