摘要:眾所周知,中參數(shù)是按值傳遞的。先大概介紹按值傳參基本類型基本類型的參數(shù)傳遞比較簡單,示例代碼的值復制給了函數(shù)內(nèi)部的局部變量所以在函數(shù)內(nèi)部改變的值并不會影響外部的值。
眾所周知,JavaScript中參數(shù)是按值傳遞的。與訪問變量不同,基本類型和引用類型的參數(shù)在傳遞時都如同變量的復制。
但是我們在使用引用類型的參數(shù)傳遞時,經(jīng)常會發(fā)現(xiàn)在函數(shù)內(nèi)改變引用類型參數(shù)(如對象)會在函數(shù)外反映出來,這種情況貌似與“按值傳參”的思想不符?
我本人在這個坑上也摔過很多次,最近遇到了一個新詞:call by sharing(按共享傳參)讓我對這個問題有了比較深刻的認識。分享給對這個問題有誤解的童鞋們。。。
先大概介紹按值傳參
基本類型的參數(shù)傳遞比較簡單,示例代碼
function add(num){ num+=10; console.log(num); } var str=10; add(str);//20 console.log(str);//10
str的值復制給了函數(shù)add內(nèi)部的局部變量num,所以在函數(shù)內(nèi)部改變num的值并不會影響外部str的值。
引用類型紅寶書上有這么一句話:在向參數(shù)傳遞引用類型的值時,會把這個值在內(nèi)存中的地址復制給一個局部變量,因此這個局部變量的變化會反應(yīng)函數(shù)外。
用兩段代碼來說明:
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"
這個情況就比較有趣了,如果是按引用傳遞的,函數(shù)內(nèi)函數(shù)外始終訪問用一個引用,最后的結(jié)果應(yīng)該是“Tom”才對。
再回到之前提到的:在向參數(shù)傳遞引用類型的值時,會把這個值在內(nèi)存中的地址復制給一個局部變量,因此這個局部變量的變化會反應(yīng)函數(shù)外。
其實這句話從另一個角度講,就是call by sharing(共享傳參)的定義。
先看一下ECMAScript中對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.
其實這段話,特別是標粗的地方說明的就是:引用類型把在內(nèi)存中的地址復制給了函數(shù)中的局部變量。
所以出現(xiàn)會兩種情況:
改變引用類型的屬性
當在函數(shù)中改變引用類型(如對象)的屬性時,是在同一個內(nèi)存地址區(qū)域進行操作,所以會在函數(shù)外反映出來。如setName1
列表項目
在函數(shù)內(nèi),對形參進行了重新復制,即改變了形參的引用,(內(nèi)存中的地址已經(jīng)改變),與實參引用已經(jīng)完全不一樣了,所以不會對函數(shù)外引用類型變量參數(shù)產(chǎn)生影響,如setName2.
個人愚見,歡迎交流討論。。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/79538.html
摘要:它對數(shù)組和對象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時成為的副本。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章節(jié),可...
摘要:它對數(shù)組和對象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時成為的副本。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章節(jié),可...
摘要:所以傳遞給函數(shù)的值是這個值,所以函數(shù)執(zhí)行結(jié)束原始變量并不會改變。傳值調(diào)用在傳值調(diào)用中,傳遞給函數(shù)參數(shù)是函數(shù)被調(diào)用時所傳實參的拷貝。引用類型變量的值是一個指針,指向堆內(nèi)存中的實際對象。所以傳共享調(diào)用也可以說是傳值調(diào)用。 1. 例子 先來看兩個個來自于 《JavaScript 高級程序設(shè)計》P70-P71 的兩個例子。 1.1. 基本類型參數(shù)傳遞 function addTen(num) ...
摘要:圖示如下而對于引用類型的復制可不是這樣這個復制只是將的引用賦值給,二者是屬于同一個引用,訪問的都是堆內(nèi)存中的同一個對象,任何一個該引用的變量發(fā)生變化,會對其余使用該引用的變量也發(fā)生變化。 這兩天自己在寫代碼的時候,出現(xiàn)一個BUG,代碼如下: class Car { constructor(carId) { this.position =...
摘要:默認參數(shù)有了我們不需要再去檢測哪些值為并且給它們設(shè)定默認值了。我們甚至可以使用函數(shù)去找回默認參數(shù)的值注意這個函數(shù)只有在第二個參數(shù)省略時才會被調(diào)用。瀏覽器對默認參數(shù)的支持情況桌面瀏覽器移動端瀏覽器解構(gòu)賦值解構(gòu)賦值是的新特性。 原文地址:https://www.smashingmagazine.com/2016/07/how-to-use-arguments-and-parameters...
閱讀 3165·2023-04-25 18:54
閱讀 2665·2021-11-02 14:40
閱讀 3276·2021-09-23 11:58
閱讀 2490·2019-08-30 13:50
閱讀 1289·2019-08-29 12:46
閱讀 3177·2019-08-28 17:51
閱讀 733·2019-08-26 11:47
閱讀 954·2019-08-23 16:17