---
# System prepended metadata

title: ［week 1］傳值(by Value)、傳址(by Reference)

---

［week 1］傳值(by Value)、傳址(by Reference)
===

在 Javascript 中，參數的傳遞分為「傳值」和「傳址」兩種方法：
* 傳值可稱為 Call by value 或 Pass by value
* 傳址則稱為 Call by reference 或 Pass by reference，或是有時候也會聽到的「傳參考」

先來看看第一個例子
```javascript=
let a = '皮卡丘';   //  宣告a並賦值為'皮卡丘'字串
let b;
b = a;             // 將b值指定等於a字串
console.log(b);    // 印出'皮卡丘'

b = '妙蛙種子';      // 再將 b 的內容重新賦值為'妙蛙種子'

console.log(a);    // 印出'皮卡丘'
console.log(b);    // 印出'妙蛙種子'
```
看起來沒有問題，我們再來看下一個
```javascript=
let a = {pokemon:'皮卡丘'}// 宣告a並賦值為pokemon:'皮卡丘'的物件
let b;
b = a;                  //  將b值指定等於a物件
console.log(b);         // {pokemon:'皮卡丘'}

b.pokemon = '妙蛙種子';  // 將b的pokemon重新賦值為'妙蛙種子'

console.log(a);       // {pokemon:'妙蛙種子'} 等等，好像哪裡怪怪的!?
console.log(b);       // {pokemon:'妙蛙種子'}
```

為什麼明明只有b改動，a裡面的皮卡丘卻會被換成妙蛙種子呢？

## 傳值(by Value)
在JS裡，以下這六個原始型別(Primitive Type)皆屬於傳值。

* Boolean 布林值
* String 字串
* Number 數字
* Null 空值
* Undefined 未定義
* Symbol 符號 (ES6 新型別)


看看以下例子
```javascript=
let a = 3;
let b = 6;
a = 9;
```
![](https://i.imgur.com/U9HEy8v.png)
在我們宣告一個變數並賦值給他時，記憶體便會留一個空間給值
若僅宣告變數沒有賦值給他，記憶體仍會預留值為undefined的空間

回到最前面一開始的例子
![](https://i.imgur.com/Jv3CIiu.png)

在宣告a和b變數後，我們將b值指定等於a值
此時記憶體便會給變數b一個空間，並copy a的值放在裡面
因此，之後b被重新賦值時
a並不會受到影響

## 傳址(by Reference)
除了基本型別以外，其他型別便皆是物件型別，以傳址方式傳遞，而包含物件本身共有三個型別皆屬於此類。
* 物件 Object
* 陣列 Array
* 函式 Function

我們來看看最前面的兩個例子
在宣告a和b物件變數後，我們將b值指定等於a值
![](https://i.imgur.com/MNmfEDr.png)
此時記憶體不會另開一個空間複製a值
b值會直接指向a值記憶體空間所在地方

因此當我們對b重新賦值時，實際上我們是在對a原本的位置做更動
![](https://i.imgur.com/DKnN1QW.png)


## 總結
原始型別是以「值」互相傳遞，也就是傳值(by Value)
物件型別是以「記憶體位置」互相傳遞，也就是傳址(by Reference)

不過除了傳值及傳址，也有人認為JS更傾向「Pass by Sharing」。

那Pass by Sharing又是什麼呢？
我們可以將Pass by sharing 視為融合了 by value 和 by reference：

* 基本型別，便是 Pass by value 。
* 物件型別，如果只是針對內容改變，便是 Pass by reference，但是如果對物件重新賦值的話，則是 Pass by value。

不過無論如何，最重要的便是在寫code時知道知道自己寫的變數為何種傳遞型式，如此才可以避免bug的產生


## 參考資料

[Javascript中的傳值 by value 與傳址 by reference](https://medium.com/itsems-frontend/javascript-pass-by-value-reference-sharing-5d6095ae030b)

[JavaScript Day 19. by value ( 傳值 ) 與 by reference ( 傳址 )](https://ithelp.ithome.com.tw/articles/10273802?sc=hot)

[Javascript 的參數傳遞：by reference（傳址/傳參考）、by value（傳值）和 by sharing（傳共享）](https://sylvia-h.github.io/posts/2021/1013_byvalue_reference_sharing/)

[問你喔，傳值(Pass by Value)、傳址(Pass by Reference) 到底在傳什麼？](https://karennnnovelty.medium.com/%E3%84%9F%E5%95%8F%E4%BD%A0%E5%96%94-%E5%82%B3%E5%80%BC-pass-by-value-%E5%82%B3%E5%9D%80-pass-by-reference-%E5%88%B0%E5%BA%95%E5%9C%A8%E5%82%B3%E4%BB%80%E9%BA%BC-5603d96830ed)
