記住真理: js函數傳遞參數,無論是簡單數據類型,仍是引用數據類型,都是值傳遞!!
下面是js紅包書裏面的例子:
function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; }var person = new Object();setName(person);alert(person.name); // "Nicholas"
確定有人會問了,既然是值傳遞,那麼我對setName這個函數傳遞了person對象,在函數裏面對person對象進行修改,爲何會對全局的person 產生影響呢?
首先,咱們要清楚,person 這個變量,是指向堆內存中一個對象的地址,這點要銘記!因此,它值傳遞複製給函數參數的,就是
指向堆內存中那個對象的地址
,這也就是爲何函數內部對這個參數的修改會體如今外部的緣由了,由於它們都指向同一個對象呀。
請看圖:
若是是引用傳遞,第二格中的內容整個傳遞進去,就不會有第四格的存在了,也就是說,若是是引用傳遞,person 函數的參數是對person 變量的一個引用,那麼堆內存中 那個對象只有一個引用地址;
事實是值傳遞,person 函數的參數複製了一份對堆內存中那個對象的地址,堆內存中 那個對象有兩個引用地址;若是我在函數內部,對該參數進行了修改,其實是對堆內存中的那個對象進行了修改;
再看這道題:
- 函數形參b是指向堆內存中的那個對象,被修改了
- 函數形參b被指向另一個空對象,堆內存中的那個對象只有全局的b 還在引用
- 函數形參b引用的空對象被修改,同時在這一行代碼執行完後,被銷燬
var b = {b:1}; function addB(b){ b.b++; // b={}; // b.b=3; // } addB(b); // b變量對堆內存中對象的引用地址,被複制了一份,賦值到函數形參上 console.log(b.b);