摘要:眾所周知,中參數(shù)是按值傳遞的。先大概介紹按值傳參基本類(lèi)型基本類(lèi)型的參數(shù)傳遞比較簡(jiǎn)單,示例代碼的值復(fù)制給了函數(shù)內(nèi)部的局部變量所以在函數(shù)內(nèi)部改變的值并不會(huì)影響外部的值。
眾所周知,JavaScript中參數(shù)是按值傳遞的。與訪問(wèn)變量不同,基本類(lèi)型和引用類(lèi)型的參數(shù)在傳遞時(shí)都如同變量的復(fù)制。
但是我們?cè)谑褂靡妙?lèi)型的參數(shù)傳遞時(shí),經(jīng)常會(huì)發(fā)現(xiàn)在函數(shù)內(nèi)改變引用類(lèi)型參數(shù)(如對(duì)象)會(huì)在函數(shù)外反映出來(lái),這種情況貌似與“按值傳參”的思想不符?
我本人在這個(gè)坑上也摔過(guò)很多次,最近遇到了一個(gè)新詞:call by sharing(按共享傳參)讓我對(duì)這個(gè)問(wèn)題有了比較深刻的認(rèn)識(shí)。分享給對(duì)這個(gè)問(wèn)題有誤解的童鞋們。。。
先大概介紹按值傳參
基本類(lèi)型的參數(shù)傳遞比較簡(jiǎn)單,示例代碼
function add(num){ num+=10; console.log(num); } var str=10; add(str);//20 console.log(str);//10
str的值復(fù)制給了函數(shù)add內(nèi)部的局部變量num,所以在函數(shù)內(nèi)部改變num的值并不會(huì)影響外部str的值。
引用類(lèi)型紅寶書(shū)上有這么一句話(huà):在向參數(shù)傳遞引用類(lèi)型的值時(shí),會(huì)把這個(gè)值在內(nèi)存中的地址復(fù)制給一個(gè)局部變量,因此這個(gè)局部變量的變化會(huì)反應(yīng)函數(shù)外。
用兩段代碼來(lái)說(shuō)明:
function setName1(obj){ obj.name="Mike"; return obj; } var person=new Object(); setName1(person); console.log(person.name);//"Mike"
這段代碼表面上看:函數(shù)內(nèi)部的改變影響了函數(shù)外,難道是按引用傳遞?再看下面這段代碼:
function setName2(obj){ obj.name="Mike"; obj={name:"Tom"}; return obj; } var person=new Object(); setName2(person); console.log(person.name);//"Mike"
這個(gè)情況就比較有趣了,如果是按引用傳遞的,函數(shù)內(nèi)函數(shù)外始終訪問(wèn)用一個(gè)引用,最后的結(jié)果應(yīng)該是“Tom”才對(duì)。
再回到之前提到的:在向參數(shù)傳遞引用類(lèi)型的值時(shí),會(huì)把這個(gè)值在內(nèi)存中的地址復(fù)制給一個(gè)局部變量,因此這個(gè)局部變量的變化會(huì)反應(yīng)函數(shù)外。
其實(shí)這句話(huà)從另一個(gè)角度講,就是call by sharing(共享傳參)的定義。
先看一下ECMAScript中對(duì)call by sharing的定義
The main point of this strategy is that function receives the copy of the reference to object. This reference copy is associated with the formal parameter and is its value.
Regardless the fact that the concept of the reference in this case appears, this strategy should not be treated as call by reference (though, in this case the majority makes a mistake), because the value of the argument is not the direct alias, but the copy of the address.
The main difference consists that assignment of a new value to argument inside the function does not affect object outside (as it would be in case of call by reference). However, because formal parameter, having an address copy, gets access to the same object that is outside (i.e. the object from the outside completely was not copied as would be in case of call by value), changes of properties of local argument object — are reflected in the external object.
其實(shí)這段話(huà),特別是標(biāo)粗的地方說(shuō)明的就是:引用類(lèi)型把在內(nèi)存中的地址復(fù)制給了函數(shù)中的局部變量。
所以出現(xiàn)會(huì)兩種情況:
改變引用類(lèi)型的屬性
當(dāng)在函數(shù)中改變引用類(lèi)型(如對(duì)象)的屬性時(shí),是在同一個(gè)內(nèi)存地址區(qū)域進(jìn)行操作,所以會(huì)在函數(shù)外反映出來(lái)。如setName1
列表項(xiàng)目
在函數(shù)內(nèi),對(duì)形參進(jìn)行了重新復(fù)制,即改變了形參的引用,(內(nèi)存中的地址已經(jīng)改變),與實(shí)參引用已經(jīng)完全不一樣了,所以不會(huì)對(duì)函數(shù)外引用類(lèi)型變量參數(shù)產(chǎn)生影響,如setName2.
個(gè)人愚見(jiàn),歡迎交流討論。。。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79538.html
摘要:它對(duì)數(shù)組和對(duì)象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲(chǔ)在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時(shí)成為的副本。 這是專(zhuān)門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可...
摘要:它對(duì)數(shù)組和對(duì)象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲(chǔ)在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時(shí)成為的副本。 這是專(zhuān)門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可...
摘要:所以傳遞給函數(shù)的值是這個(gè)值,所以函數(shù)執(zhí)行結(jié)束原始變量并不會(huì)改變。傳值調(diào)用在傳值調(diào)用中,傳遞給函數(shù)參數(shù)是函數(shù)被調(diào)用時(shí)所傳實(shí)參的拷貝。引用類(lèi)型變量的值是一個(gè)指針,指向堆內(nèi)存中的實(shí)際對(duì)象。所以傳共享調(diào)用也可以說(shuō)是傳值調(diào)用。 1. 例子 先來(lái)看兩個(gè)個(gè)來(lái)自于 《JavaScript 高級(jí)程序設(shè)計(jì)》P70-P71 的兩個(gè)例子。 1.1. 基本類(lèi)型參數(shù)傳遞 function addTen(num) ...
摘要:圖示如下而對(duì)于引用類(lèi)型的復(fù)制可不是這樣這個(gè)復(fù)制只是將的引用賦值給,二者是屬于同一個(gè)引用,訪問(wèn)的都是堆內(nèi)存中的同一個(gè)對(duì)象,任何一個(gè)該引用的變量發(fā)生變化,會(huì)對(duì)其余使用該引用的變量也發(fā)生變化。 這兩天自己在寫(xiě)代碼的時(shí)候,出現(xiàn)一個(gè)BUG,代碼如下: class Car { constructor(carId) { this.position =...
摘要:默認(rèn)參數(shù)有了我們不需要再去檢測(cè)哪些值為并且給它們?cè)O(shè)定默認(rèn)值了。我們甚至可以使用函數(shù)去找回默認(rèn)參數(shù)的值注意這個(gè)函數(shù)只有在第二個(gè)參數(shù)省略時(shí)才會(huì)被調(diào)用。瀏覽器對(duì)默認(rèn)參數(shù)的支持情況桌面瀏覽器移動(dòng)端瀏覽器解構(gòu)賦值解構(gòu)賦值是的新特性。 原文地址:https://www.smashingmagazine.com/2016/07/how-to-use-arguments-and-parameters...
閱讀 3079·2023-04-25 18:54
閱讀 2598·2021-11-02 14:40
閱讀 3193·2021-09-23 11:58
閱讀 2438·2019-08-30 13:50
閱讀 1243·2019-08-29 12:46
閱讀 3129·2019-08-28 17:51
閱讀 687·2019-08-26 11:47
閱讀 907·2019-08-23 16:17