1.基本類型值指的是簡單的數據段。常見的有5種基本數據類型:Undefined、
Null、Boolean、Number和String。這5種基本數據類型是按值訪問的,因爲可
以操作保存在變量中的實際的值。
2.引用類型值指的是那些可能由多個值構成的對象。JavaScript不允許直接訪
問內存中的位置,即不能直接操作對象的內存空間。在操作對象時,實際上是
在操作對象的引用而不是實際的對象。所以,引用類型的值是按引用訪問的。
3.動態的屬性:
對於引用類型的值,我們可以爲其添加屬性和方法,也可以修改或刪除其屬性
和方法。參見如下的例1:
例1:
var person=new Object();
person.name="Kim";//爲對象添加name的屬性
alert(person.name);//此時成功輸出person.name的值爲Kim
person.name="Frank";
alert(person.name);//此時輸出爲Frank,說明person.name的值被修改了
但我們不能給基本類型的值添加屬性,以例2來說明:
例2: var man="Tom";
alert(man);//輸出爲Tom,沒問題
man.age="21";
alert(man.age);//此時輸出值爲undefined
綜合以上的例1和例2,說明只能給引用類型值動態的添加屬性。
4.複製變量值:
如果從一個變量向另一個變量複製基本類型值,會在變量對象上創建一個新值,然後
把該值複製到爲新變量分配的位置上,此時兩個變量分別存儲着相同的值,但互不影
響。如例3:
例3:
var num1 = 1;
var num2 = num1;
alert("num1="+num1+"\n"+"num2="+num2);//此時輸出的兩個變量值都爲1
num1=2;
alert("num1="+num1+"\n"+"num2="+num2);//此時num1=2,num2=1
當從一個變量向另一個變量複製引用類型的值時,此時複製的是一個指針,指向存儲在
堆中的一個對象。當複製操作結束後,兩個變量實際上引用的是同一個對象,若改變其中
的一個變量,就會影響另一個變量。如例4所示:
例4:
var person=new Object();
var man=person;
person.name="Kim";//爲對象添加name的屬性
alert(man.name);//輸出Kim
man.name="John";
alert(person.name);//輸出John
5.傳遞參數:
ECMAScript中所有函數的參數都是按值傳遞的。也就是說,把函數外部的值複製給函數
內部的參數,就和把值從一個變量複製到另一個變量一樣。基本類型值的傳遞如同基本類
型變量的複製;而引用類型值的傳遞就如同引用類型變量的複製。訪問變量有兩種方式:
按值方式和按引用的方式,而參數只能按值傳遞。
當傳遞的是基本類型的值時,參見例5:
例5:
function sum(num){
num+=10;
return num;
}
var count=10;
var res=sum(count);
alert(count);
//輸出值爲10,count是基礎類型,當傳遞參數時是複製變量的值給參數
alert(res);
//輸出值爲20,num只是和count的值相同,二者互不影響
例5說明基本類型的值在傳遞參數的時候是按值傳遞的,如果是按引用傳遞的
話,count的值應該是20。
當傳遞的是引用類型的值時,參見如下例6:
例6:
function setName(obj){
obj.name="Tim";
obj={};
obj.name="John";
}
var nm={};
//定義nm爲一個空對象
setName(nm);
//調用函數setName,併爲其傳遞參數,此時的參數是一個對象
alert(nm.name);
//輸出結果爲Tim
對於例6,如果傳遞了參數nm時,假設nm的傳參方式是按引用傳遞的,我們可做如下分析:
代碼7:
function setName(obj){
//當nm是按引用傳遞時,此時的obj可替換爲nm
obj.name="Tim";
//這行代碼可以替換爲 nm.name="Tim"
obj={};
//將nm轉化爲空對象
obj.name="John";
//修改num的name屬性值爲"John"
}
var nm={};
setName(nm);
alert(nm.name);
//此時的輸出值應爲John,但結果並不是!
由代碼7的分析可知:引用類型的傳參不是按引用傳遞。
所以引用類型傳參只能是按值傳遞。
那麼,對於代碼7我們應該這樣來理解:
代碼8:
function setName(obj){ //當nm是按值傳遞時,此時的obj和nm的指針相同
均指向內存中的同一個對象
obj.name="Tim";
//nm.name="Tim",即是內存中的對象的name屬性值
obj={};
//此時將obj的指針進行改變,指向的是一個空對象
但nm的指針指向並未改變!
obj.name="John";
//將obj指向的對象的對象的name屬性值修改爲"John"
}
var nm={};
setName(nm);
alert(nm.name);
//此時輸出的是nm所指向的對象的name屬性,仍爲"Tim"
例8說明:即是在函數內部修改了參數的值,原始的引用仍保持不變。而且重寫的對象是一
個局部變量,在函數執行完畢之後就會被銷燬。