關(guān)于function.bind以及函數(shù)的值傳遞與引用傳遞

在看Promise迷你書遇到一段代碼一開始沒有理解,然后就查了一下bind的使用以及函數(shù)的值傳遞與引用傳遞。代碼大致如下:

function recordValue(results, value) {
    results.push(value);
    return results;
}
var pushValue = recordValue.bind(null, []);
console.log(pushValue(1)) 
console.log(pushValue(2)) 

一開始我以為結(jié)果會是

[1]
[2]

但是實際結(jié)果是

[1]
[1,2]

function.prototype.bind

然后以為bind的參數(shù)我理解的有問題,我去查了一下api,下面是bind函數(shù)的解釋。

bind()函數(shù)會創(chuàng)建一個新函數(shù)(稱為綁定函數(shù)),新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標函數(shù))具有相同的函數(shù)體(在 ECMAScript 5 規(guī)范中內(nèi)置的call屬性)。當新函數(shù)被調(diào)用時 this值綁定到bind()的第一個參數(shù),該參數(shù)不能被重寫。綁定函數(shù)被調(diào)用時,bind()也接受預設(shè)的參數(shù)提供給原函數(shù)。一個綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當成構(gòu)造器。提供的 this值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)。

簡單來說就是改變某個方法內(nèi)部的this指向,同時可以指定該函數(shù)的參數(shù)。我和理解的沒什么大問題,我的理解就是它將recordValuethis綁定為null,并且將第一個參數(shù)綁定為[],所以我會覺得結(jié)果是[1][2]。然后我打斷點發(fā)現(xiàn)第二次執(zhí)行pushValue的時候recordValue函數(shù)的第一個參數(shù)變成了[1],不再是[]。所以我就考慮到了函數(shù)的引用傳遞。

然后我試了一下改造一下,結(jié)果和我第一次預期的一樣

function recordValue(results, value) {
    results = results+value;
    return results;
}
var pushValue = recordValue.bind(null, "");
console.log(pushValue("hello")) 
console.log(pushValue("word")) 

這個時候結(jié)果又變成了

hello
world

這個時候我再改造一下

function recordValue(results, value) {
    results.a = results.a + value
    return results;
}
var pushValue = recordValue.bind(null, {a:0});
console.log(pushValue(1)) //
console.log(pushValue(2)) //
//-------結(jié)果----------//
{ a: 1 }
{ a: 3 }

這個時候就明顯的是引用傳遞所以導致的第二次執(zhí)行的時候第一個參數(shù)變了,不再為[]
最上面的代碼var pushValue = recordValue.bind(null, []);在綁定參數(shù)為[]的時候,相當于初始化一個數(shù)組對象,而數(shù)組不是基本類型,是引用類型,作為函數(shù)的參數(shù)的時候就是引用傳遞。

js的變量類型

js的數(shù)據(jù)類型分為兩種類型:
1.基本類型
包括Undefined, Null, Boolean, Number和String五種基本數(shù)據(jù)類型
2.引用類型
保存在內(nèi)存中的對象們,不能直接操作,只能通過保存在變量中的地址引用對其進行操作

值傳遞

所以當函數(shù)的參數(shù)為基本類型的時候,它將保存的值’hello‘賦值給形參,他們只是值一樣,地址不同。所以函數(shù)體內(nèi)不管怎么改變形參,實參都不會跟著改變


值傳遞

引用傳遞

那么當參數(shù)為引用類型的時候,實參將其內(nèi)部保存的對象的內(nèi)存地址賦值給形參,他們兩個保存的是一個內(nèi)存地址,指向內(nèi)存堆中的同一個對象,有點類似c中的指針。這個時候形參改變了其某個屬性的值的時候其實改變的是指向的內(nèi)存堆中對象的屬性值。所以函數(shù)執(zhí)行完成后,實參內(nèi)存的地址雖然不變,但指向的對象已經(jīng)改變了,所以實參會跟著形參變。


引用傳遞1

所以函數(shù)執(zhí)行完畢后,實參從[]變成了[1]。

還有一種情況,如果形參在函數(shù)體內(nèi)改變的不是引用的對象,而是重新賦值,比如指向一個新的對象results = {x:1}或者賦值一個基本類型results = 0,那么實參不變。因為指向一個新的變量都是改變形參內(nèi)存中存的值,這個新的值可以是一個基本類型也可能是新的內(nèi)存對象的地址。值變了之后,但實參內(nèi)存中的值還是之前對象的地址,所以和形參不一樣。

引用傳遞2

其實,引用傳遞也是值傳遞,只是傳遞的是引用罷了。之所以有引用傳遞這種說法應該是為了讓大家更好明白概念。

關(guān)于函數(shù)的引用傳遞與值傳遞的可以看這篇文章,強烈推薦,尤其是評論下面的討論。
以及這篇文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容