可是,沒有類,何來面向對象一說?沒有關系,可以模擬。而且這一套方法已經成為公認的JS實現面向對象的方法。
另外,JS內的東西完全開發,也就不存在成員的什麼private、protected作用域。
下面切入正題。
一、類型 //從基礎開始,省的後面看著吃力
1、類型的區別
基本數據類型和對象類型不是一回事。
a、基本類型只是一個值,沒有任何行為;而對象類型有自己的行為。
b、基本類型是值類型,僅表示一個值;對象類型則擁有許多復雜的東西。
c、基本類型傳遞時傳值,對象類型傳遞時傳址。
另外,文本非常特殊,JS裡面有兩種文本類型——一種基本數據類型,一種對象類型。 舉個例子:
var str="The End";//這樣是基本數據類型,傳遞方式就是傳值
var str2=new string("The End");//這就不同,有了new這個為對象開辟內存空間的標識符,對應的變量就會成為對象類型,傳遞時即傳址
簡單點說: a、直接用字面量賦值的變量,如var a=1;var b="a";var c=true;,都是基本數據類型(常用的有:數值、文本、布爾)
b、用new賦值的變量,如var a=new Object();var b=new string();,都是對象類型(JS有許多對象,算是精簡的面向對象語言) 請注意:基本數據類型也可以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在傳遞對象類型時,也拷貝了一份相應類型的對象,但是副本對象的所有屬性、函數都是原對象的屬性、函數。