基本數據類型和引用類型
- 2020 年 5 月 26 日
- 筆記
- javascript
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里就不用管了。
以上就是本人總結的基本數據類型和引用類型的一些異同,由於本人也是初學者,難免會發生一些錯誤,望各位網友批評指正,互相學習。