作者 魏楷聰 發布于 2015年01月20日
一種面向對象語言需要向開發者提供四種基本能力:
1. 封裝 - 把相關的信息(無論數據或方法)存儲在對象中的能力
2. 聚集 - 把一個對象存儲在另一個對象內的能力
3. 繼承 - 由另一個類(或多個類)得來類的屬性和方法的能力
4. 多態 - 編寫能以多種方法運行的函數或方法的能力
在JavaScript中,所有對象都是從Object對象繼承過來的。Object中的屬性都是不可枚舉的(propertyIsEnumerable返回false),因此無法通過for...in語句得到其中的屬性。
在JavaScript中,可以動態添加對象的屬性,也可以動態刪除對象的屬性。
1) 基于已有對象擴充其屬性和方法
最后一個屬性sayName實際上是指向函數的指針,意味著該屬性是個方法。
2) 工廠方式(factory function)
使用this,即可在任意多個地方重用同一個函數
注意:引用對象的屬性時,必須使用this關鍵字。
function get(){
?????? alert(username + ", " + password);
}
如果不用對象或this關鍵字引用變量,ECMAScript就會把它看作局部變量或全局變量。然后該函數將查找名為color的局部或全局變量,但是不會找到。結果該函數將報“username未定義”的錯誤。
3) 構造函數方式
4) 原型(“prototype”)方式
能用 instanceof 運算符檢查給定變量指向的對象的類型:
alert(person1 instanceof Person);? // outputs "true"
利用對象的prototype屬性,可把它看成創建新對象所依賴的原型
調用new Person()時,原型的所有屬性都被立即賦予要創建的對象,
意味著所有Person實例存放的都是指向getInfo()函數的指針
由于username是引用值,Person的兩個實例都指向同一個數組
如果使用原型方式對象,那么生成的所有對象會共享原型中的屬性,這樣一個對象改變了該屬性(引用值)也會反映到其它對象當中。
單純使用原型方式定義對象無法在構造函數中為屬性賦初值,只能在對象生成后再去改變屬性值。
使用原型+構造函數方式來定義對象,對象之間的屬性互不干擾,各個對象間共享同一個方法。
用原型方式定義對象的函數屬性(方法)
所有函數都只創建一次(沒有內存浪費),而每個對象都具有自己的對象屬性實例
5) 動態原型方式:在構造函數中通過標志量讓所有對象共享一個方法,而每個對象擁有自己的屬性
(完)