1. 程式人生 > >JavaScript是按引用傳遞or值傳遞?

JavaScript是按引用傳遞or值傳遞?

克隆 undefine 棧內存 問題: data- defined 同時 log js基礎

今遇js基礎類型等問題,已經有點模糊,遂作總結。

前言:

JavaScript原始類型:Undefined、Null、Boolean、Number、String、Symbol JavaScript引用類型:Object;

原始類型又被稱為基本類型,原始類型保存的變量和值直接保存在棧內存(Stack)中,且空間相互獨立,通過值來訪問;雖然原始類型的值是儲存在相對獨立空間,但是它們之間的比較是按值比較的;

引用類型即Object 類型,再往下細分,還可以分為:Object 類型、Array 類型、Date 類型、Function 類型 等。與原始類型不同的是,引用類型的內容是保存在堆內存中,而棧內存(Heap)中會有一個堆內存地址,通過這個地址變量被指向堆內存。

1.JavaScript中的基本類型傳遞

一個我們經常遇到的問題:“JS中的值是按值傳遞,還是按引用傳遞呢?”

由於js中存在復雜類型和基本類型,對於基本類型而言,是按值傳遞的.

var a = 1;
function test(x) {
  x = 10;
  console.log(x);
}
test(a); // 10
console.log(a); // 1

雖然在函數testa被修改,並沒有有影響到 外部a的值,基本類型是按值傳遞的.


2.復雜類型按引用傳遞?

我們將外部a作為一個對象傳入test函數.

var a = {
  a: 1,
  b: 2
};
function test(x) {
  x.a = 10;
  console.log(x);
}
test(a); // { a: 10, b: 2 }
console.log(a); // { a: 10, b: 2 }

可以看到,在函數體內被修改的a對象也同時影響到了外部的a對象,可見復雜類型是按引用傳遞的.

可是如果再做一個實驗:

var a = {
  a: 1,
  b: 2
};
function test(x) {
  x = 10;
  console.log(x);
}
test(a); // 10
console.log(a); // { a: 1, b: 2 }

外部的a並沒有被修改,如果是按引用傳遞的話,由於共享同一個堆內存,a在外部也會表現為10才對.
此時的復雜類型同時表現出了按值傳遞按引用傳遞的特性.


3.按共享傳遞

復雜類型之所以會產生這種特性,原因就是在傳遞過程中,對象a先產生了一個副本a

,這個副本a並不是深克隆得到的副本a,副本a地址同樣指向對象a指向的堆內存.

技術分享圖片

因此在函數體中修改x=10只是修改了副本a,a對象沒有變化. 但是如果修改了x.a=10是修改了兩者指向的同一堆內存,此時對象a也會受到影響.

有人講這種特性叫做傳遞引用,也有一種說法叫做按共享傳遞.

JavaScript是按引用傳遞or值傳遞?