基本數據類型和引用類型

js將數據類型分為基礎類型和引用類型,通俗地講,基礎類型都是單一結構,而引用類型都可以看做對象,即複合結構。二者在複製時會有不同的行為,且不同類型在函數傳值時的表現也不同,本文將帶領大家發現二者之間的不同和類似之處。
首先要介紹js的記憶體模型:
首先,js記憶體區域分為堆和棧,先介紹棧的部分
js運行時,會存在一個運行環境,這一部分及作用域的概念已於作用域部分進行介紹,在此不多贅述。而系統會在每個運行環境中建立一個變數對象,用於保存那些存在於該運行環境中的變數,這個變數對象就保存於棧中。
而堆中則用於保存其餘所有的對象,包括用戶自己創建的對象等。
對於保存基本數據類型的變數,其值全部保存在變數對象中,即存儲於棧中,而保存引用類型的變數,其引用的對象保存在堆中,而變數中保存的是其引用,即其在堆中的地址。

var x=10;
var y=new Object();

一.二者複製時的情形
    1.基本數據類型在複製時會將值傳遞給新的變數,在那之後新舊變數之間沒有任何關係。
如:

var x=10;
var y=x;
y++;
console.log(x);
console.log(y);

結果為:

 

 

 

    2.引用類型複製時僅將引用值傳遞給新變數,在那之後二者同時指向同一個對象,因此對該對象進行的操作同時影響兩個變數
如:

 

 

var x=new Object();
var y=x;
y.num=10;
console.log(x.num);
console.log(y.num);

結果為:

 

總結:
其實很容易發現,複製時僅將棧內變數對象中對應變數的值賦值給了新變數,只不過二者保存的內容不同才導致所謂的傳值和傳引用的不同。

二.函數傳值時二者的表現
js函數參數的傳遞一律使用傳值,按上述總結的結果,可得出如下情形
1.基本數據類型
由上文可推知,傳遞到函數中的值應當與原變數毫無關係,以下來驗證該推理:

var x=10;
console.log("傳遞參數之前x的值:");
console.log(x);
function add1(num){
    num++;
}
add1(x);
console.log("傳遞參數之後x的值:");
console.log(x);

結果為:

說明函數中的++操作並未影響到x,由此得證

2.引用類型
同理可推知,函數中的參數一定是得到了原變數中引用的地址值,從而也指向了同一個堆中對象,因此函數中對該值的改變會波及原變數

var x=new Object();
x.num=20;
function add2(ref){
    ref.num++;
}
add2(x);
console.log(x.num);

結果為:

 

 得證

三.傳引用
前面提到js中函數參數一律採用傳值,那所謂的傳引用又是什麼情形呢?
以基本數據類型為例,傳值是將變數中的值賦值給新變數,那麼傳引用其實就是將原變數的引用,即地址傳遞給新變數,從而使得新舊變數相互綁定,新變數名可以看做是原變數的別名,改變新變數的值也會影響原變數。這個概念會出現在C++中,而在js里就不用管了。

 

以上就是本人總結的基本數據類型和引用類型的一些異同,由於本人也是初學者,難免會發生一些錯誤,望各位網友批評指正,互相學習。