「轉(zhuǎn)」JavaScript函數(shù)參數(shù)按值傳遞

作者:蘇墨橘

鏈接:https://www.zhihu.com/question/27114726/answer/35481766

來源:知乎

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。



數(shù)據(jù)類型


在 javascript 中數(shù)據(jù)類型可以分為兩類:

原始數(shù)據(jù)類型值 primitive type,比如Undefined,Null,Boolean,Number,String。

引用類型值,也就是對象類型 Object type,比如Object,Array,Function,Date等。

聲明變量時不同的內(nèi)存分配

原始值:存儲在棧(stack)中的簡單數(shù)據(jù)段,也就是說,它們的值直接存儲在變量訪問的位置。這是因為這些原始類型占據(jù)的空間是固定的,所以可將他們存儲在較小的內(nèi)存區(qū)域 – 棧中。這樣存儲便于迅速查尋變量的值。

引用值:存儲在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內(nèi)存地址。這是因為:引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響。


不同的內(nèi)存分配機制也帶來了不同的訪問機制


在javascript中是不允許直接訪問保存在堆內(nèi)存中的對象的,所以在訪問一個對象時,首先得到的是這個對象在堆內(nèi)存中的地址,然后再按照這個地址去獲得這個對象中的值,這就是傳說中的按引用訪問。而原始類型的值則是可以直接訪問到的。


復(fù)制變量時的不同

原始值:在將一個保存著原始值的變量復(fù)制給另一個變量時,會將原始值的副本賦值給新變量,此后這兩個變量是完全獨立的,他們只是擁有相同的value而已。

引用值:在將一個保存著對象內(nèi)存地址的變量復(fù)制給另一個變量時,會把這個內(nèi)存地址賦值給新變量,也就是說這兩個變量都指向了堆內(nèi)存中的同一個對象,他們中任何一個作出的改變都會反映在另一個身上。(這里要理解的一點就是,復(fù)制對象時并不會在堆內(nèi)存中新生成一個一模一樣的對象,只是多了一個保存指向這個對象指針的變量罷了)

參數(shù)傳遞的不同


首先我們應(yīng)該明確一點:ECMAScript中所有函數(shù)的參數(shù)都是按值來傳遞的。但是為什么涉及到原始類型與引用類型的值時仍然有區(qū)別呢,還不就是因為內(nèi)存分配時的差別。 (我對比了一下,這里和復(fù)制變量時遵循的機制完全一樣的嘛,你可以簡單地理解為傳遞參數(shù)的時候,就是把實參復(fù)制給形參的過程)

原始值:只是把變量里的值傳遞給參數(shù),之后參數(shù)和這個變量互不影響。

引用值:對象變量它里面的值是這個對象在堆內(nèi)存中的內(nèi)存地址,這一點你要時刻銘記在心!因此它傳遞的值也就是這個內(nèi)存地址,這也就是為什么函數(shù)內(nèi)部對這個參數(shù)的修改會體現(xiàn)在外部的原因了,因為它們都指向同一個對象呀。或許我這么說了以后你對書上的例子還是有點不太理解,那么請看圖吧:

圖片發(fā)自簡書App


所以,如果是按引用傳遞的話,是把第二格中的內(nèi)容(也就是變量本身)整個傳遞進去(就不會有第四格的存在了)。但事實是變量把它里面的值傳遞(復(fù)制)給了參數(shù),讓這個參數(shù)也指向原對象。因此如果在函數(shù)內(nèi)部給這個參數(shù)賦值另一個對象時,這個參數(shù)就會更改它的值為新對象的內(nèi)存地址指向新的對象,但此時原來的變量仍然指向原來的對象,這時候他們是相互獨立的;但如果這個參數(shù)是改變對象內(nèi)部的屬性的話,這個改變會體現(xiàn)在外部,因為他們共同指向的這個對象被修改了呀!來看下面這個例子吧:(傳說中的call by sharing)

var obj1 = {

?value:'111'

};

var obj2 = {

?value:'222'

};

function changeStuff(obj){

?obj.value = '333';

?obj = obj2;

?return obj.value;

}

var foo = changeStuff(obj1);

console.log(foo);// '222' 參數(shù)obj指向了新的對象obj2

console.log(obj1.value);//'333'

code里的注釋太小看不清,我移到這里來:

/* obj1仍然指向原來的對象,之所以value改變了, *是因為changeStuff里的第一條語句,這個時候obj是指向obj1的 . *再啰嗦一句,如果是按引用傳遞的話,這個時候obj1.value應(yīng)該是等于'222'的 */

好了,以上就是關(guān)于這個問題的全部解釋了。

各位有興趣的話可以去了解一下call by value ,call by reference call by sharing 等函數(shù)傳遞的機制call by sharing

還有stackoverflow上對于函數(shù)傳遞的這個問題解釋得相當(dāng)精辟,值得一看。(下面有鏈接)


參考:

ECMAScript 原始值和引用值

Is JavaScript a pass-by-reference or pass-by-value language?

紅寶書《javascript高級程序設(shè)計》P69-P71


------------2017-4-11更新 ----------

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容