6面向对象的程序设计
ECMA_262把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或者函數。
6.1理解對象
特性(attribute)是內部值,描述了屬性(property)的各種特性。ECMAScript中有兩種屬性:數據屬性和訪問器屬性。數據屬性包含一個數據值的位置,在這個位置可以讀取和寫入值,數據屬性有4個描述其行為的特性,[[Configurable]],[[Enumerable]],[[Writable]],[[Value]].要改變屬性默認的特性,必須使用ECMAScript5的Object.defineProperty()方法,這個方法接收3個參數:屬性所在的對象、屬性的名字和一個描述符對象,一旦把屬性定義為不可配置的,就不能再把它變回可配置了。訪問器屬性不包含數據值,它們包含一對getter和setter函數,訪問器屬性有4個特性:[[Configurable]],[[Enumerable]],[[Get]],[[Set]].
Object.defineProperties()方法可以一次定義多個屬性。
Object.getOwnProperyDescriptor()方法,可以取得給定屬性的描述符,這個方法接收兩個參數:屬性所在的對象和要讀取其描述符的屬性名稱。
6.2創建對象
工廠模式用函數來封裝以特定接口創建對象的細節。工廠模式雖然解決了創建多個相似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個對象的類型)。
使用構造函數模式可以定義自定義對象類型的屬性和方法。按照慣例,構造函數始終都應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭。創建自定義的構造函數意味著將來可以將它的實例標識為一種特定的類型,而這正是構造函數模式勝過工廠模式的地方。構造函數與其他函數的唯一區別,就在于調用它們的方式不同,任何函數,只要通過new操作符來調用,那它就可以作為構造函數。使用構造函數的主要問題,就是每個方法都要在每個實例上重新創建一遍。
我們創建的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含由特定類型的所有實例共享的屬性和方法。使用原型對象的好處是可以讓所有對象實例共享它所包含的屬性和方法。與構造函數模式不同的是,新對象的這些屬性和方法是由所有實例共享的。只要創建了一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象,所有原型對象都會自動獲得一個constructor(構造函數)屬性,這個屬性包含一個指向prototype屬性所在函數的指針。連接存在于實例和構造函數的原型對象之間,而不是存在于實例和構造函數之間。Object.getPrototypeOf()方法返回[[Prototype]]的值??梢酝ㄟ^對象實例訪問保存在原型中的值,但卻不能通過對象實例重寫原型中的值,當為對象實例添加一個屬性時,這個屬性就會屏蔽原型對象中保存的同名屬性,使用delete操作符則可以完全刪除實例屬性,從而讓我們能夠重新訪問原型中的屬性。使用hasOwnProperty()方法可以檢測一個屬性是否存在于實例中,還是存在于原型中(在對象實例中,才會返回true)。有兩種方式使用in操作符:單獨使用和在for-in循環中使用。單獨使用時,in操作符會通過對象能夠訪問給定屬性是返回true,不論該屬性存在于實例中還是原型中。在使用for-in循環時,返回的是所有能夠通過對象訪問、可枚舉的(enumerated)屬性,其中即包括存在于實例中的屬性,也包括存在于原型中的屬性。Object.keys()方法可以取得對象上所有可枚舉的實例屬性。Object.getOwnPropertyNames()方法可以得到所有實例屬性,無論是否可枚舉。用對象字面量來重寫原型對象,constructor屬性也就變成了新對象的constructor屬性(指向Object構造函數),不再指向Person函數。重寫原型對象切斷了現有原型與任何之前已經存在的對象實例之間的聯系。原型模式省略了為構造函數傳遞初始化參數這一環節,結果所有實例在默認情況下都取得相同的屬性值,原型模型最大問題是由其共享的本性多導致的。
創建自定義類型的最常見方式,就是組合使用構造函數模式與原型模式,構造函數模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。
動態原型模型把所有信息都封裝在了構造函數中,而通過在構造函數中初始化原型(僅在必要的情況下),有保持了同時使用構造函數和原型的優點。換句話說,可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
寄生構造函數模式的基本思想是創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然后在返回新創建的對象。返回的對象與構造函數或者與構造函數的原型屬性之間沒有關系。
所謂穩妥對象,指的是沒有公共屬性,而且其方法也不引用this的對象。穩妥對象最適合在一些安全的環境,或者在防止數據被其他應用程序改動時使用。
6.3繼承
ECMAScript中描述了原型鏈概念,并將原型鏈作為實現繼承的主要方法。其基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。所有函數的默認原型都是Object的實例,因此默認原型都會包含一個內部指針,指向Object.prototype。使用instanceof操作符和isPrototypeOf()方法可以確定原型和實例之間的關系,只要是實例和原型鏈中出現過的構造函數,結果就會返回true。再通過原型鏈實現繼承時,不能使用對象字面量創建原型方法,因為這樣做就會重寫原型鏈。原型鏈最主要的問題來自包含引用類型值的原型,第二個問題是在創建子類型的實例時,不能向超類型的構造函數中傳遞函數,實際上,應該說是沒有辦法在不影響所有對象實例的情況下,給超類型的構造函數傳遞參數。
借用構造函數的基本思想是在子類型構造函數的內部調用超類型構造函數。相對于原型鏈而言,借用構造函數有一個很大的優勢,即可以在子類型構造函數中向超類型構造函數傳遞參數。如果僅僅是借用構造函數,那么也將無法避免構造函數模式存在的問題——方法都在構造函數中定義,因此函數復用就無從談起了。
組合繼承值得是將原型鏈和借用構造函數的技術組合到一起,其背后的思路是使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承,這樣,既通過在原型上定義方法實現了函數復用,有能保證每個實例都有它自己的屬性。
原型式繼承要求必須有一個對象可以作為另外一個對象的基礎。如果有這么一個對象的話,可以把它傳遞給object()函數,然后在根據具體需求對得到的對象加以修改即可。Object.create()方法規范化了原型式繼承,這個方法接收兩個參數:一個用作新對象原型的對象和(可選的)一個為新對象定義額外屬性的對象。包含引用類型值的屬性時鐘都會共享相應的值,就像使用原型模式一樣。
寄生式繼承的思路與寄生構造函數和工廠模式類似,即創建一個僅用于封裝繼承過程的函數,該函數在內部以某種方式來增強對象,最后再像真地是它做了所有工作一樣返回對象。在主要考慮對象而不是自定義類型和構造函數的情況下,寄生繼承也是一種有用的模式。
?
轉載于:https://www.cnblogs.com/dingzibetter/p/6296908.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的6面向对象的程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到被偷被抢是什么意思
- 下一篇: 怀孕梦到油菜花是什么意思