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