JavaScript 函數(shù)參數(shù)是傳值(byVal)還是傳址(byRef) 分享
對(duì)于“JavaScript 函數(shù)參數(shù)是傳值(byVal)還是傳址(byRef)”這個(gè)問(wèn)題,普遍存在一個(gè)誤區(qū):number,string等“簡(jiǎn)單類(lèi)型”是傳值,Number, String, Object, Array等“復(fù)雜類(lèi)型”是傳址。
這樣不對(duì)嗎?為什么會(huì)有這樣的誤區(qū)?看一下這兩段代碼:
//造成傳值假象的代碼
function modifyLikeByVal(x){
x = 1;
console.log('x = %d', x);
}
var x = 0;
console.log('x = %d', x); // 輸出 x = 0
modifyLikeByVal(x); // 輸出 x = 1
console.log('x = %d', x); // 輸出 x = 0 x沒(méi)變!
//造成傳址假象的代碼
function modifyLikeByRef(x){
x[0] = 4;
x[1] = 5;
x[2] = 6;
console.log('x = [ %s ]', x.join(', '));
}
var x = [1, 2, 3];
console.log('x = [ %s ]', x.join(', ')); // 輸出 x = [ 1, 2, 3 ]
modifyLikeByRef(x); // 輸出 x = [ 4, 5, 6 ]
console.log('x = [ %s ]', x.join(', ')); // 輸出 x = [ 4, 5, 6 ] x變了!
于是,由以上代碼得出結(jié)論,“簡(jiǎn)單類(lèi)型”作為參數(shù)是傳值(byVal)的,“復(fù)雜類(lèi)型”作為參數(shù)是傳址(byRef)的。
問(wèn)題出在哪呢?
仔細(xì)觀(guān)察兩個(gè)函數(shù),就可以發(fā)現(xiàn)一點(diǎn):
在byVal中,是直接修改了參數(shù)x: x = 1;
而byRef中,是修改參數(shù)x的成員: x[0] = 4; x[1] = 5; x[2] = 6;
本人由此得出猜想:在JavaScript中,所有的變量或成員,都是一個(gè)指針,在修改變量或成員值的時(shí)候,其實(shí)是修改了該指針的地址。
這樣上面的代碼就可以得到解釋了:
在“byVal”中:
global { // 表示全局作用域,下面的表示函數(shù)作用域
var x = 0; // 初始化指針x并指向數(shù)字0
fun(x) {
x = global.x; // 傳入?yún)?shù)global.x; fun域的x指針地址與global域的x指針地址一樣指向數(shù)字0
x = 1; // 修改fun域的x指針地址,指向數(shù)字1;
} // fun 域結(jié)束,global域中的x指針沒(méi)改變
}
在“byRef”中:
global { // 表示全局作用域,下面的表示函數(shù)作用域
/*
初始化指針x并指向數(shù)組[1, 2, 3]
其實(shí)是x的三個(gè)成員0, 1, 2,分別指向1, 2, 3;
*/
var x = [1, 2, 3];
fun(x) {
x = global.x; // 傳入?yún)?shù)global.x; fun域的x指針地址與global域的x指針地址一樣指向數(shù)組[1, 2, 3]
/*
在fun域中的x沒(méi)有再被改變
緊接著修改fun域中的x(也就是global.x)三個(gè)成員指針的指向
*/
x[0] = 4;
x[1] = 5;
x[2] = 6;
} // fun 域結(jié)束,global域中的x指針沒(méi)改變,但其三個(gè)成員指針被改變了,于是就看到我們輸出的結(jié)果
}
那這段代碼怎么解釋呢???
(function(a, b){
arguments[0] = 1;
b = 2;
console.log(arguments, a, b);
})(-1, -2);
只能說(shuō)a, b...,是arguments[0],...[n]的別名了。
如果有不對(duì)的地方,請(qǐng)指出來(lái),謝謝。
如果有更好的解釋?zhuān)瑲g迎大家分享。
相關(guān)文章
js實(shí)現(xiàn)一個(gè)簡(jiǎn)易計(jì)算器
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)一個(gè)簡(jiǎn)易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Javascript實(shí)現(xiàn)圖片懶加載插件的方法
最近由于公司項(xiàng)目需要,要利用Javascript實(shí)現(xiàn)圖片懶加載效果,嘗試起來(lái)發(fā)現(xiàn)并不難,于是將自己的實(shí)現(xiàn)過(guò)程分享出來(lái)給大家學(xué)習(xí)和參考,希望對(duì)有需要的朋友們帶來(lái)一定的幫助,感興趣的朋友們下面來(lái)一起看看吧。2016-10-10JS連接SQL數(shù)據(jù)庫(kù)與ACCESS數(shù)據(jù)庫(kù)的方法實(shí)例
這篇文章主要介紹了JS連接SQL數(shù)據(jù)庫(kù)與ACCESS數(shù)據(jù)庫(kù)的方法實(shí)例,有需要的朋友可以參考一下2013-11-11js報(bào)錯(cuò):Maximum?call?stack?size?exceeded的解決方法
這篇文章主要給大家介紹了關(guān)于js報(bào)錯(cuò)Maximum?call?stack?size?exceeded的解決方法,文中通過(guò)實(shí)例代碼將解決的方法介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02詳談js中標(biāo)準(zhǔn)for循環(huán)與foreach(for in)的區(qū)別
下面小編就為大家?guī)?lái)一篇詳談js中標(biāo)準(zhǔn)for循環(huán)與foreach(for in)的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11JS實(shí)現(xiàn)Excel導(dǎo)出功能以及導(dǎo)出亂碼問(wèn)題解決詳解
這篇文章主要為大家詳細(xì)介紹了JavaScript如何調(diào)用后臺(tái)接口實(shí)現(xiàn)Excel導(dǎo)出功能以及導(dǎo)出亂碼問(wèn)題的解決辦法,需要的小伙伴可以參考一下2023-07-07在Javascript操作JSON對(duì)象,增加 刪除 修改的簡(jiǎn)單實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇在Javascript操作JSON對(duì)象,增加 刪除 修改的簡(jiǎn)單實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06Bootstrap時(shí)間選擇器datetimepicker和daterangepicker使用實(shí)例解析
這篇文章主要為大家詳細(xì)解析了Bootstrap時(shí)間選擇器datetimepicker和daterangepicker使用實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09