JavaScript是按引用傳遞or值傳遞?
阿新 • • 發佈:2019-02-19
克隆 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
雖然在函數test
中a
被修改,並沒有有影響到 外部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值傳遞?