本文介紹了幾乎所有關于對象的基本概念,什么是對象,如何創建對象,對象的屬性的設置和讀取,刪除屬性的方法,構造函數,對象原型,父類,子類,繼承等等。
1.對象
* 對象是一種復合數據類型,它們將多個數據值集中在一個單元中,而且運行使用名字來存取這些值。解釋對象的另一種方式是,對象是一個無序的屬性集合,每個屬性都有自己的名字和值。存儲在對象中的已命名的值可以是數字和字符串這樣的原始值,也可以是對象。
*/
var o = new Object();
2.對象直接量創建對象
* 對象直接量由屬性說明列表構成,列表包含在大括號中,其中的屬性說明由逗號隔開。
* 對象直接量中的每個屬性說明都由屬性名加上冒號和屬性值構成。
*/
var zhangsan = {name:”zhangsan”, age:34, married:true};
window.alert(typeof zhangsan); //輸出object
3.屬性的讀取和設置
* 對象的屬性通過點號運算符讀取和設置。對象的新屬性可以通過直接創建。
*/
window.alert(zhangsan.car); //輸出undefined
zhangsan.car=”BMW”; //直接賦值
window.alert(zhangsan.car); //輸出BMW
4.屬性的枚舉
* 通過for循環枚舉每一個屬性,順序不能保證固定。
* 注意枚舉出的是屬性名稱,并不是屬性值。
*/
var values = “”;
for(var v in zhangsan)values += v+”\n”; //枚舉每一個屬性
window.alert(values);
5.屬性的刪除使用delete,如delete zhangsan.car
*/
6.構造函數
* 構造函數是具有兩個特性的javascript函數:
* (1)它由new 運算符調用;
* (2)傳遞給它的是一個對新創建的空對象的應用,將該引用作為關鍵字this的值,而且它還要對新創建的對象進行適當的初始化。
* 記?。簶嬙旌瘮抵皇浅跏蓟瘜ο?,并不返回新創建的對象。
*/
function Rectangle(w, h){
this.width = w;
this.height = h;
}
var ret1 = new Rectangle(2, 1);
//注意構造函數是如何使用它的參數來初始化this關鍵字所引用的對象的屬性
7.對象的方法
* 所謂方法,就是通過對象調用的javascript函數。我們知道,函數就是數值,它們所使用的名字沒有任何特殊之處,可以將函數賦給任何變量,甚至賦給一個對象的任何屬性,那么這個屬性就是對象的方法了。
* 在對象的方法體內,關鍵字this的值就成了調用該方法的對象。
*/
function print(){}
ret1.print = print;
8.關于this的討論
* 任何一個用作方法的函數都會得到一個額外的實際參數,即調用該函數的對象。由于方法通常是對那個對象執行某種操作,所以要表達函數作用于對象這一事實,最好采用方法的調用語法。
* 如rect.setSize(width, height);
* setSize(rect, width, height);
* 雖然這兩行代碼對對象rect執行相同的操作,但是第一行代碼在表達對象rect是操作的焦點(或者說操作的目標)這一觀點時顯然清楚得多。
*
* 雖然有區別地對待函數和方法比較有用,但實際上它們之間的差別并不大?;貞浺幌?,函數是存儲在變量中的值,而那個變量也不過是全局對象的一個屬性。因此,當你調用一個函數時,實際上調用的是全局對象的一個方法。
* 在這樣的函數中,關鍵字this引用的是全局對象。所以函數和方法之間在技術上沒有差別,真正的差別在于設計和目的上,方法是用來對this對象進行操作的,而函數通常會是獨立的,并不需要使用this對象。
*/
(function f(){
var values = “”;
for(var v in this)values += v + ” “;
window.alert(values);
})(); //返回window對象的所有屬性和方法名稱
9.原型對象和繼承
* javascript每個對象都有原型對象,每個對象都繼承原型對象的所有屬性。
* 一個對象的原型是由創建并初始化該對象的構造函數定義的。javascript中的所有函數都有prototype屬性,它引用了一個對象。雖然原型對象初始化時是空的,
* 但是你在其中定義的任何屬性都會被該構造函數創建的所有對象繼承。
*
* 構造函數定義了對象的類,并初始化了類中狀態變量的屬性,如width和height。因為原型對象和構造函數關聯在一起,所以類的每個成員都從原型對象繼承了相同的屬性。
* 這說明原型對象是存放方法和其他常量屬性的理想場所。
* 注意,繼承是在查詢一個屬性值時自動發生的。屬性并非從原型對象復制到新的對象的,它們只不過看起來像是那些對象的屬性。這其中有兩點重要的含義。
* 一是使用原型對象可以大量減少每個對象對內存的需求量,因為對象可以繼承許多屬性。二是即使屬性在對象被創建之后才添加到它的原型對象中,對象也能夠繼承這些屬性。
*
* 每個類都有一個原型對象,這個原型對象都具有一套屬性。但是實際上卻有大量的類實例,每個實例都能繼承原型對象的屬性。由于一個原型對象能夠被多個對象繼承,所以javascript
* 必須強化讀寫屬性值之間的不對稱性。在讀對象o的屬性p時,javas會首先檢查o是否具有一個名為p的屬性。如果o沒有這個屬性,javascript就會再檢查o的原型對象是否具有這個屬性。這樣才使得以原型為基礎的繼承機制起作用。
*
* 但是當寫一個屬性的值時,javascript并不會檢查原型對象中是否有這個屬性的值。因為,如果允許改變原型對象的這一屬性,那就改變了整個對象類的p值,包括其他new出來的對象變量的屬性值。
*
* 因此,屬性的繼承只發生在讀屬性值時,而不會發生在寫屬性值時。如果你設置的對象o的屬性p是對象o從它的原型對象繼承而來的,那么結果就是你直接在對象o中創建了一個新屬性p?,F在o已經有了一個自己的名為p的屬性,它就不會再從它的原型對象繼承p的值了。當你讀p的值時,java首先查詢o的屬性。
* 由于它發現了o中定義的p,就不必再查詢原型對象,也就不會再發現原型對象中定義的p值了。我們稱之為o中的p”遮蔽”了或者說”隱藏”了原型對象中的屬性p。
*
* 因為原型對象的屬性被一個類的所有對象共享,所以通常只用它們來定義類中所有對象的相同的屬性。這使得原型對象適用于方法定義和常量的定義。
*/
10. 實例屬性、實例方法、類屬性、類方法
* 每個對象都有它自己單獨的實例屬性的副本。我們說javas中的實例屬性是那些在對象中用構造函數創建的或初始化的屬性。
*
* 實例方法是由特定對象或實例調用的。實例方法使用了關鍵字this來引用它們要操作的對象或實例。雖然一個類的任何實例都可以調用實例方法,并不意味著每個對象都像實例屬性那樣含有自己專有的方法副本。相反,每個實例方法都是由類的所有實例共享的。在javascript中,給類定義一個實例方法,是通過把構造函數的原型對象中的一個屬性設置為函數值來實現的。
* 這樣,由那個構造函數創建的所有實例都會共享一個已繼承的對函數的引用。
*
* 類屬性表示在所有類實例中只有一個副本。在javascript中,類屬性本質上就是全局變量。但是它們與一個類關聯在一起,在javascript的名字空間中擁有一個邏輯位置,這樣它們就不會被其他的同名屬性覆蓋。
* 如Circle.PI=3.14。雖然Circle是一個構造函數,但是由于javascript函數是對象,所以我們可以創建函數的屬性,就像創建對象的屬性一樣。
*
* 類方法與類屬性相似。在javascript中,要定義一個類方法,只需要用合適的函數作為構造函數的屬性即可。
*/
11. 父類和子類
* 在javascript中,Object類所有類的父類,處于類層次圖的最上層。所有的類都繼承了Object類的所有方法。
*
* 我們已經學會了對象如何從它們構造函數的原型對象中繼承屬性,那么它們又是如何繼承類Object的屬性哪?我們知道,原型對象本身就是一個對象,它是由構造函數Object()創建的。
* 這就意味著原型對象繼承了Object.prototype屬性。因此,ret1會繼承Rectangle.prototype的屬性,還會繼承Object.prototype的屬性。整因為所有對象的prototype屬性會繼承Object.prototype屬性,
* 所以所有javascript子類都繼承了Object的所有屬性,也即Object類是javascript的根類,處于類層次圖的最頂層。
*/
12.使用[]讀取和設置對象的屬性
* 通常會采用點號運算符訪問對象的屬性,但是點號后面的屬性是標識符。在javascript中,標識符必須逐字輸入,它們不是一種數據類型。如果程序中屬性是動態的、不確定的,那么我們將無法訪問。
* 前面解釋過,對象是一群屬性的集合,也就是數組。那么可以使用數組訪問成員的運算符[]來訪問對象的屬性。[]中是屬性名稱,是字符串類型,我們就可以動態的確定對象屬性名稱了。
*
* 使用[]運算符的對象我們也稱之為關聯數組。關聯數組是一種數據結構,允許你動態地將任意值和任意字符串關聯在一起。實際上,javascript對象在內部就是用關聯數組實現的。使用點號運算符只是為了是他們看起來更像C++和Java的靜態對象而已。
*
* 前面的for/in循環實際上是對數組的操作。
*
* 我們通常意義說的數組是將任何值和非負整數關聯在一起的數據結構。
*
* 數組實際上是一個具有額外功能層的對象。如var a = new Array();window.alert(typeof a);輸出Object。
*/
13. Object類的屬性和方法
* constructor屬性表示初始化該對象的構造函數。因此,可以使用該屬性來判斷對象的類型。
*/
function A(){return “aaaaaaaaa”};
var a = new A();
window.alert(a.constructor); //輸出的是A的函數定義
window.alert(a.constructor==A); //結果是true
window.alert(a.constructor()); //輸出aaaaaaaaaa
/**
* toString()方法沒有任何實際參數,它返回的是一個字符串,該字符串代表了調用它的對象的類型或值。當javascript需要將一個對象轉化成字符串時就調用這個對象的toString方法。
* 例如,當用運算符”+”把一個字符串和一個對象連接到一起時,或者把一個對象傳遞給alert()或document.write()方法時,就會調用toString()方法。
*/