---
# System prepended metadata

title: 傳值與傳址
tags: [' 六角筆記王', ' hexo部落格', JavaScript]

---

---
tags:  JavaScript, hexo部落格, 六角筆記王
title: 傳值與傳址
---

## 情況
某天，自己需要更改陣列資料時，遇到一個莫名其妙的情況。

修正前 : 
```javascript 
// 原始資料陣列
let data = [
 {
   name: 'A'
 },
 {
   name: 'B'
 }
];
// 暫存資料
let temp = {
  name: 'C'
};

data.forEach(item => {
  if (item.name === 'B'){
    item = temp
  }
})
console.log(data[1]) // { name: 'B'}
```
`變數 data` 內的資料，居然還是原封不動!

修正後 : 
```javascript 
data.forEach(item => {
  if (item.name === 'B'){
    item.name = temp.name
  }
})
console.log(data[1]) // { name: 'C'}
```
`變數 data` 內的資料終於修改成功了!

不過，為什麼會這樣?

--- 

## 傳值

當我們宣告一個新的變數時，其預設值會是 `undefined` ，

若我們賦予這個變數一個值，後續取用這個變數時，就會是其值，

像是這樣 : 
```javascript 
let a = 1
console.log(a) // 1
```

若我們再宣告一個`變數 b`並賦予其值為`變數 a`，`變數 b` 的值會是?
```javascript 
let b = a
console.log(b) // ?
```
此時狀態會是"傳遞值"，也就是說`變數 b`的值會是 1，

若我們再將`變數 a`重新賦予值為 100，`變數 b` 也不會被改變其值。

> 在 JavaScript 裡，布林值、字串、數值、null、undefined 都是 Pass by value。

```javascript 
// 完整範例
let a = 1
let b = a
a = 100
console.log(b) // 1
```

---

## 傳址 / 傳參考

上面的情況都是純值，換成物件、陣列或是函式呢?

假設我們程式碼如下 : `變數 b` 會是?
```javascript 
let a = {
  name: 'A'
}
let b = a
a = 1
console.log(b.name) // ?
```

`變數 b` 不會受到變動，因為它是傳值，因此 `b.name` 為 `'A'`。

若變更物件的屬性值呢? 
```javascript 
let a = {
  name: 'A'
}
let b = a
a.name = 'B'
console.log(b.name) // 'B'
```
變更物件屬性值時，`變數 b`連帶的也受到影響，也就是傳參考。

> 在 JavaScript 裡，物件、陣列、函式都是 Pass by reference。

那我們知道有這樣情況後，使用函式來看看會怎樣?

```javascript 
// 宣告一樣的變數作為範例
let d = {
  name: 'D'
}
let e = {
  name: 'E'
}
const fn = data => {
  data = e
}
fn(d) 
console.log(d) // ?
```
在上述的範例中，`變數 d`維持不變，因為它是傳值，
若改成 `data.name = e.name`，此時才會是傳參考。

## 回歸情況
回到一開始的程式碼，很單純地想讓資料變更，於是重新賦予其值，

但事實沒這麼簡單，由於 JavaScript 擁有兩種特性，傳值與傳參考，特別是物件，

單純的物件複製是傳值，修改物件屬性值則為傳參考，

於是產生了 Pass by sharing 來稱呼這種情況。


## 參考來源
> 1. [SimonAllen - Day17 傳值 by value 與傳址 by reference](https://ithelp.ithome.com.tw/articles/10192342)
> 2. [Kuro Hsu - 重新認識 JavaScript: Day 05 JavaScript 是「傳值」或「傳址」？](https://ithelp.ithome.com.tw/articles/10191057) 
> 3. [OneJar - 你不可不知的 JavaScript 二三事#Day26：程式界的哈姆雷特 —— Pass by value, or Pass by reference？](https://ithelp.ithome.com.tw/articles/10209104)
