可是,沒有類,何來物件導向一說?沒有關係,可以類比。而且這一套方法已經成為公認的JS實現物件導向的方法。
另外,JS內的東西完全開發,也就不存在成員的什麼private、protected範圍。
下面切入正題。
一、類型 //從基礎開始,省的後面看著吃力
1、類型的區別
基礎資料型別 (Elementary Data Type)和物件類型不是一回事。
a、基本類型只是一個值,沒有任何行為;而物件類型有自己的行為。
b、基本類型是實值型別,僅表示一個值;物件類型則擁有許多複雜的東西。
c、基本類型傳遞時傳值,物件類型傳遞時傳址。
另外,文本非常特殊,JS裡面有兩種文本類型——一種基礎資料型別 (Elementary Data Type),一種物件類型。 舉個例子:
var str="The End";//這樣是基礎資料型別 (Elementary Data Type),傳遞方式就是傳值
var str2=new string("The End");//這就不同,有了new這個為對象開闢記憶體空間的標識符,對應的變數就會成為物件類型,傳遞時即傳址
簡單點說: a、直接用字面量賦值的變數,如var a=1;var b="a";var c=true;,都是基礎資料型別 (Elementary Data Type)(常用的有:數值、文本、布爾)
b、用new賦值的變數,如var a=new Object();var b=new string();,都是物件類型(JS有許多個物件,算是精簡的物件導向語言) 請注意:基礎資料型別 (Elementary Data Type)也可以new,但是很少有那種用法。因此上述區分辦法不完全適用所有情況,請加以自行判斷。
2、參數傳遞方式 這一節主要來區分傳址、傳值。 仍然拿例子來說事: 複製代碼 代碼如下:function changeVar(varible){
varible=5;
alert(varible);//提示5
}
var a=3;
alert(a);//提示3
changeVar(a);//該函數內部有改變參數的代碼 alert(a);//仍然提示3
根據上例可以發現,函數雖然改變了參數,但是並沒有改變參數所代表的傳遞過去變數。這是傳值。在調用changeVar時,JS重新拷貝了一份你傳遞的變數作為參數,所以,在changeVar內部操作的參數實際上是你傳遞的變數的副本,而非本身。 傳遞的其實是變數的值,而非變數本身。這叫做傳值。 複製代碼 代碼如下:function changeVar(varible){
varible.x=5;
alert(varible.x);//提示5
}
var a=new Object;
a.x=3 alert(a.x);//提示3
changeVar(a);//該函數內部有改變參數的代碼
alert(a.x);//提示5
上例改成使用Object對象了。發現,changeVar之後,原來的變數的對應屬性也發生改變,函數內部就是操作的傳遞的變數本身。 傳址就是這個道理,把你給定的變數的記憶體位址傳遞過去,函數內部改變的其實就是你傳遞的變數。因為操作的都是在統一記憶體位址的東西。
但是,一定注意這個“但是”!JS的傳址還是有些特別之處! JS在傳遞物件類型時,大概也拷貝了一份相應類型的對象,但是副本對象的所有屬性、函數都是原對象的屬性、函數。 也許就是,屬性傳址而對象不傳址。 這個特點可以證明。 代碼如下: 複製代碼 代碼如下:function changeVar(varible){
varible=new Object();
varible.x=5;
alert(varible.x);//提示5
}
var a=new Object;
a.x=3 alert(a.x);//提示3
changeVar(a);//該函數內部有改變參數的代碼
alert(a.x);//提示3
當你改變了參數代表的對象時,並未改變的了你傳遞的變數代表的對象。但前面說過,可以通過函數內對參數對象的屬性操作改變原變數代表對象的屬性。這結合起來就可以證明,JS在傳遞物件類型時,也拷貝了一份相應類型的對象,但是副本對象的所有屬性、函數都是原對象的屬性、函數。