談談值傳遞

ECMAScript變量可能包含兩種不一樣的數據類型:基本數據類型和引用數據類型,這兩種類型的值傳遞是存在不一樣的.javascript

在咱們談這兩種數據類型的值傳遞前,爲了便於理解,我想首先談一下這兩種數據類型有關複製操做存在的不一樣前端

數據類型的複製

基本類型

var num1 = 10;
var num2 = num1;
    num2 = 11;
console.log(num1);//10
console.log(num2);//11

基本數據類型從一個複製到另外一個,會在變量對象上建立一個新值,而後把該值複製到新變量分配的位置上,改變其中一個不會影響另外一個。java

本小白用拙劣的畫功演示一下數組

圖片描述

一開始聲明變量num1並賦值爲10,它便以圖中的形式存在某種結構中,當用num1的值來初始化num2的時候,此時就至關於聲明變量num2並賦值爲num1中的值,該值只是num1中的一個副本,賦值結束,這兩個變量便再無瓜葛,進行後面的操做也不會相互影響函數

引用類型

引用類型咱們採用數組,數組的聲明有兩種方式,一種爲var 數組名 = []另外一種爲var 數組名 = new array()spa

var arr1 = [1,2,3,4];
var arr2 = arr1;
    arr2[0] = 10;
console.log(arr1);//[10,2,3,4]
console.log(arr2);//[10,2,3,4]

此處及下文輸出省略掉數組長度,能夠看出輸出的結果都爲[10,2,3,4]. 和基本數據類型徹底不一樣.code

圖片描述

當聲明數組變量並賦值的時候,一樣也會存入一個結構當中,可是這個結構不能存[1,2,3,4]這種數據,要存到堆中去,就是圖片右邊那個橢圓形的區域,可是存入的數據仍是要找到它。每一個存儲位置都有相應的地址,因此它在左邊那個結構中存入的是一個指向數組對象的這樣的一個地址。對象

圖片描述

當複製引用類型變量的時候,一樣也會將存儲在左邊結構中的值複製一份放到爲新變量分配的空間中去,只不過由於這個值的副本是一個指向堆中原數組對象的地址,兩個變量名就至關於引用了同一個地址中的內容。所以,改變其中的一個變量,就會影響另外一個blog

var arr3=[1,2,3,4];
var arr4=arr3;
arr4=[5,6,7,8];
console.log(arr3);//[1,2,3,4]
console.log(arr4);//[5,6,7,8]

這個相比於前面那個,只是在第三行代碼中出現了不一樣,arr4=[5,6,7,8]將一個新的數組對象賦給變量arr4,這時arr4後的地址就改變了,也就指向了新的數組對象,這兩個變量也就徹底不相同了.圖片

圖片描述

能夠實驗一下console.log(new Array(1,2)===new Array(1,2)),這個在控制檯返回的是false

那好,如今有了這些鋪墊,咱們再來談咱們今天的主要內容.

數據類型的值傳遞

基本類型

var num = 10;

function change(num){
  num = 11;
  console.log(num);//11
}

change(num);
console.log(num);//10

在像參數傳遞基本類型的值時,被傳遞的值會被先複製給一個局部變量,其實就能夠理解爲基本數據類型的賦值。以上的代碼也能夠寫爲這樣

var num = 10;

function change(){
  var num = 10;//look
  num = 11;
  console.log(num);//11
}

change(num);
console.log(num);//10

在look處,函數會將參數先聲明並賦值,值就爲下面傳入的參數的值,num的值爲10,所以賦得值也爲10。但此時函數中的num和函數外部的num實際上是絕不相關的,所以並不會相互影響

引用類型

var arr = [1,2,3,4];

function change(arr){
  arr[0] = 10;
  console.log(arr);//[10,2,3,4]
}

change(arr);
console.log(arr)//[10,2,3,4]

引用類型也如此,也能夠理解爲引用類型的複製操做,在函數的開頭就會將arr賦值爲傳來的數值,雖然也是一開始聲明的引用類型的副本,可是由於引用類型傳來的數值是地址,所以函數中的arr和函數外面的arr都將引用同一個地址中的數組對象,由於arr指向的數組對象在堆中只有一個,又是全局變量,所以這兩個arr是相同的,一樣咱們再看那一種聲明數組並賦值的.

var arr=[1,2,3,4];

function change(arr) {
  arr=[4,5,6,7];
  console.log(arr);//[4,5,6,7]
}

change(arr);
console.log(arr);//[1,2,3,4]

那這個也就應該能夠理解了,雖然在傳參的時候傳入的確實是一開始聲明的數組對象的地址的副本,可是由於在函數內部又聲明瞭一個新的數組對象,在這裏arr引用的就是一個局部的數組對象了,而這個局部對象就會在函數結束後當即被銷燬,不會影響函數外部的數組對象

本小白大二學生...自學前端一年,水平有限,就先解釋這麼多了,若是有不對的還請大佬們指點,本小白定當悔過自新,從新作人.

相關文章
相關標籤/搜索