JS中函數參數值傳遞和引用傳遞

學習JS中函數參數值傳遞和引用傳遞的學習

JS中函數參數值傳遞和引用傳遞

在JavaScript紅寶書中說到,「ECMAScript中全部函數的參數都是按值傳遞的」。理解這個概念先要從JS的堆內存和棧內存提及:棧內存爲自動分配的內存空間,它由系統自動釋放;堆內存則是動態分配的內存,大小不定也不會自動釋放。(很初級的理解,有錯誤還望指正)函數

JS中的5種基本數據類型Undefined、Null、Boolean、Number 和 String,它們是直接按值存放在棧內存中,能夠直接訪問。引用類型的值是保存在堆內存中的對象。與其餘語言不一樣,JavaScript不容許直接訪問堆內存中的位置, 也就是說不能直接操做堆內存中的對象。 在操做對象時, 其實是在操做對象的引用(也可理解爲指針)而不是實際的對象。」 這個堆內存中對象的引用(指針)存儲在棧內存中。你只能操做棧內存中的數據。即基礎類型數據和堆內存中對象的指針兩大類學習

對於基本數據類型的複製就至關於你和小明買了一輛同樣的單車,你對本身單車的操做不會影響到小明的單車。
而對於引用類型的複製,至關於你和小明共用一個客廳,你對這個客廳作的操做是會影響到小明的客廳(即大家共用的客廳)測試

以下圖:
clipboard.pngspa

//測試代碼:
    //基本類型:
    var a = 10;
    var b = a;
    b = 12;
    alert(a);//10
    alert(b);//12
    
    //引用類型:
    var a = new Object();
    a.name = "Tony";
    alert(a.name);//"Tony"
    var b = a;
    b.name = "Tom"
    alert(a.name);//"Tom"

參數的傳遞

繼續說參數的傳遞,不管參數是什麼類型,都是按值傳遞的,普通類型傳遞的是自己的值,引用類型傳遞的是本身在棧內存中的「指針」值。指針

function setName(obj) {
    obj.name = "Nicholas";
}
var person = new Object();
setName(person); 
alert(person.name);   // "Nicholas"

實際過程以下圖
clipboard.png
...]code

//而有一個容易引發誤導的點在於下面這個變化
function setName(obj) {
obj.name = "Nicholas";
obj = new Object(); //改變obj的指向,此時obj指向一個新的內存地址,再也不和person指向同一個
obj.name = "Greg";
}
var person = new Object();
setName(person);  
alert(person.name);  //"Nicholas"
//這裏只要理解,你不能直接操做堆內存中的對象,你只能經過棧內存中的指針進行操做。

這個函數的過程以下圖:
clipboard.png對象

相關文章
相關標籤/搜索