js中的值傳遞和引用傳遞

在js中值傳遞和引用傳遞是讓人容易混淆的問題,下面我就來根據自己的理解來區分一下這兩個傳遞方式:

值傳遞

值傳遞是兩個變量傳遞前後互補干擾,無法造成影響,下面代碼舉例說明

var a=7;
function fuc(a){
  a++;
}
fuc(a)
console.log(a);  //7

向上面這樣,當我們給a賦值之後,在通過調用函數調用吧a的值自增,但是改變的a的值只是在函數中,沒有改變函數外部的值,這種方式傳遞叫做值傳遞,實際的原理可以用堆棧解釋一下:

當我們賦值a=7的時候,因爲數據是基本數據類型,所以存在棧中,而函數fuc的值a是引用數據類型得數據所以存在堆中,而棧中只是存放一個地址,(基本數據類型有哪些,number,string,boolean,null,undefined,symbol以及未來ES10新增的BigInt(任意精度整數)七類。引用數據類型(Object類)有常規名值對的無序對象{a:1},數組[1,2,3],以及函數function(){}等)。如下圖所示:

var a=7時;

fuc(a)時;

所以當我們打印a的值得時候a的值是保存在堆中的因而沒有變。

引用傳遞

值傳遞的時候通過函數調用之後如果沒有在函數中找到所需要的值,會去函數外面找所需要的變量及其值,改變的過程如下:

代碼:

var a=7;
function fuc(){
	a++
}
fuc(a);
console.log(a); //8

堆棧中數據存儲:

var a=7;

fuc(a)時,這時候因爲函數中沒有a變量,所以沒有數據保存到堆棧中,所以函數就會去函數外面尋找,就會找到上圖的棧中存貯的a=7,所以在函數調用的時候,改變的是函數外邊的值,也就是存儲在棧中的值。

或者換一種方式理解,代碼如下:

function test(obj){
  obj.name = 'lili';
}
var tal = new Object();
test(tal);
console.log(tal);  //{name:'lili'}

當函數test創建的時候,會創建一個對象obj:

當我們創建一個空對象tal的時候:

test(tal)的時候:tal=obj,

當調用函數的時候,因爲tal和obj都是引用數據類型,所以都把數據保存在堆中,棧中只是存一個地址,當我們賦值tal=obj的時候,這時就是把tal對象在棧中創建的地址指向改爲和obj是一樣的,都指向obj在堆中的內存數據,這種傳遞數據的方式叫做引用傳遞。

除此之外參數也是按照值傳遞的,具體代碼如下:

function test(obj){
	obj.name = 'lili';
	var obj = new Object();
	obj.name = 'kiki';
}
var tal = new Object();
test(tal);
console.log(tal);  //{name:'lili'}

堆棧中的存儲數據過程如下:

然後函數調用:

當重新聲明obj對象的時候,並且賦值之後:

這時候我們看到創建一個新對象,就相當於把obj的值放到一個新的堆中,改變對象obj的值之後,因爲tal對象還是指向之前的obj的堆,所以數據沒有改變,並且由此可以看出,對象的傳遞也是按照引用傳遞的方式來傳遞的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章