JavaScript高級程序設計(第3版)第六章讀書筆記

第六章 面向對象的程序設計app

1. 數據屬性函數

[[Configurable]]:表示可否經過delete刪除屬性從而從新定義屬性。默認值爲true。測試

[[Enumerable]]:表示可否經過for-in循環返回屬性。默認值爲true。this

[[Writable]]:表示可否修改屬性的值,默認爲true。spa

[[Value]]:包含這個屬性的數據值。默認爲undefined。prototype

要修改屬性默認的特性,必須使用ECMAScript5的Object.defineProperty( )方法。接收三個參數:屬性所在對象,屬性名字和一個描述符對象。其中,描述符對象的屬性必須是:configurable、enumerable、writable和value。設計

能夠屢次調用Object.defineProperty()方法需改同一屬性,但在把configurable特性設置爲false以後就會有限制了。指針

2. 訪問器屬性對象

訪問器屬性不包含數據值,包含一對getter和setter函數。繼承

[[Configurable]]:表示可否經過delete刪除屬性從而從新定義屬性。默認值爲true。

[[Enumerable]]:表示可否經過for-in循環返回屬性。默認值爲true。

[[Get]]:在讀取屬性時調用的函數,默認值爲undefined。

[[Set]]:在寫入屬性時調用的函數,默認值爲undefined。

定義多個屬性,ECMAScript5定義了Object.defineProperties()方法。

3. 使用ECMAScript5的Object.getOwnPropertyDescriptor()方法,能夠取得給定屬性的描述符。此方法接收兩個參數:屬性所在的對象和要讀取其描述符的屬性名稱。返回值是一個對象。

4. 建立對象

方法

細節

工廠模式

用函數來封裝以特定接口建立對象的細節。

優勢:能夠無數次調用函數。

缺點:但沒有解決對象識別的問題。

構造函數模式

沒有顯示地建立對象;

直接將屬性和方法賦給了this對象;

沒有return語句。

構造函數始終都以一個大寫字母開頭,而非構造函數應該以一個小寫字母開頭。

要建立構造函數的新實例,必須使用new操做符。

優勢:構造函數模式賽過工廠模式的地方在於:能夠將它的實例標識爲一種特定的類型。

缺點:每一個方法都要在每一個實例上從新建立一遍。

原型模式

每一個函數都有一個prototype(原型)屬性,此屬性是一個指針,指向一個對象,此對象的用途是包含能夠由特定類型的全部實例共享的屬性和方法。

當爲對象實例添加一個屬性時,這個屬性就會屏蔽原型對象中保存的同名屬性,但不會修改那個屬性。使用delete操做符則能夠徹底刪除實例屬性,可以從新訪問原型中的屬性。

hasOwnProperty( )方法能夠檢測一個屬性是存在於實例中,仍是存在於原型中。只有存在於對象實例中,纔會返回true。

單獨使用時,in操做符會在經過對象可以訪問給定屬性時返回true,不管該屬性存在於實例中仍是原型中。只要in操做符返回true,而hasOwnProperty( )返回false,就能夠肯定屬性時原型中的屬性。

hasPrototypeProperty( )方法,當原型屬性存在時,返回true,當原型屬性被實例重寫時,返回false。

在使用for-in循環時,返回的是全部可以經過對象訪問的、可枚舉的屬性,其中既包括存在於實例中的屬性,也包括存在於原型中的屬性。

重寫原型對象切斷了現有原型與任何以前已經存在的對象實例之間的聯繫,他們引用的仍然是最初的原型。

優勢:可讓全部對象實例共享它所包含的屬性和方法,即沒必要再構造函數中定義對象實例的信息,而是能夠將這些信息直接添加到原型對象中。

缺點:由共享本質,對於包含引用類型值的屬性而言問題突出。

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

建立自定義的最多見方式,也是用來定義引用類型的默認形式。

實例屬性在構造函數中定義,全部實例共享的屬性constructor和方法都在原型中定義。

優勢:集構造函數與原型模式之所長。

動態原型模式

使用if語句檢查初始化以後應該存在的任何屬性或方法。採用該模式建立的對象能夠用instanceof操做符肯定它的類型。

寄生構造函數模式

除了使用new操做符並把使用的包裝函數叫作構造函數以外,此模式與工廠模式是同樣的。構造函數在不返回值的狀況下,默認會返回新對象實例,而經過在構造函數的末尾添加一個return語句,能夠重寫調用構造函數返回的值。

返回的對象與構造函數或者構造函數的原型屬性直接沒有關係。

不能依賴instanceof操做符來肯定對象類型。

可使用其餘模式,儘可能不要使用該模式

穩妥構造函數模式

穩妥對象:沒有公共屬性,並且其方法也不引用this的對象。

與寄生構造模式的兩點不一樣:一是新建立對象的實例方法不引用this;二是不使用new操做符調用構造函數。

5. OO語言通常支持兩種繼承方式:接口集成和實現繼承。接口集成只繼承方法簽名,而實現繼承則集繼承實際的方法。ECMAScript只支持實現繼承,且主要依賴原型鏈來實現。

6. 原型鏈的基本思想是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。

functionSuperType(){

  this.property = true;

}

SuperType.prototype.getSuperValue= function( ){

  returnthis.property;

}

functionSubType(){

  this.subproperty = false;

}

SubType.prototype= new SuperType();

SubType.prototype.getSubValue= function(){

  return this.subproperty;

}

instance.getSubValue()     //false

instance.getSuperValue()   //true

7. 全部引用類型默認都集成了Object,而這個繼承也是經過原型鏈實現的。

8. 肯定原型和實例的兩種方法:一是使用instanceof操做符,用這個操做符來測試實例與原型鏈中出現過的構造函數,結果就會返回true,第二種方式是使用isPrototypeOf( )方法,只要原型鏈中出現過的原型,均可以說是該原型鏈所派生的實例的原型。

9. 給原型添加方法的代碼必定要放在替換原型的語句以後,另外,在經過原型鏈實現繼承時,不能使用對象字面量建立原型方法。

10.  繼承

方法

實現

原型鏈

利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。

原型鏈的兩大問題,一是來自包含引用類型值的原型,另外一個是在建立子類型的實例時,不能向超類型的構造函數中傳遞參數。

借用構造函數

使用apply()和call( )方法在新建立的對象上執行構造函數。

優勢:相對於原型鏈而言,能夠在子類型構造函數中向超類型構造函數傳遞參數

缺點:方法都在構造函數中定義,所以函數複用就無從談起。

組合集成

將原型鏈和借用構造函數的技術一塊兒,取長處的方式。原理是使用原型鏈實現對原型屬性和方法的集成,而經過借用構造函數來實現對實例屬性的繼承。

優勢:避免了原型鏈和借用構造函數的缺陷,融合了它們的優勢,成爲JavaScript中最經常使用的繼承模式。並且,instanceof和isPrototypeOf( )也可以用於識別基於組合繼承建立的對象。

缺點:不管什麼狀況下,都會調用兩次超類型構造函數,一次是在建立子類型原型的時候,另外一次是在子類型構造函數內部。

原型式繼承

此方法沒有嚴格意義上的構造函數,藉助原型能夠基於已有的對象建立新對象,同時還沒必要所以建立自定義類型。

ECMAScript經過新增Object.create( )方法規範化了原型式繼承。

缺點:包含引用類型值的屬性始終都會共享相應的值,就像使用原型模式同樣。

寄生式繼承

建立一個僅用於封裝繼承過程的函數,該函數在內部以某種方式來加強對象,最後再像真的處理以後同樣返回對象。

缺點:使用寄生式集成來爲對象添加函數,會因爲不能作到函數複用而下降效率

寄生組合式繼承

經過借用構造函數來繼承屬性,經過原型鏈的混成形式來繼承方法。基本思路是:沒必要爲了指定子類型的原型而調用超烈性的構造函數,咱們所須要的是超類型原型的一個副本而已。即便用寄生式繼承來繼承超類型的原型,而後再將結果指定給子類型的原型。

優勢:效率高,值調用一次超類型原型的構造函數,原型鏈還能保持不變,能正常使用instanceof和isPrototypeOf( )。是最理想的繼承範式。

相關文章
相關標籤/搜索