---
# System prepended metadata

title: 'JS學習筆記: javascript的「call by reference」'
tags: [js學習筆記]

---

# JS學習筆記: javascript的「call by reference」

今天如果我們有下面一段程式碼，他會怎麼顯示。

```javascript=
var a = [ 1, 2, 3 ]
var b = a
a.push(5)
console.log(b)
```

答案是 [1, 2, 3, 5]

改動的明明是a，b也跑來湊熱鬧跟著變動，按照原本賦值的理解，應該是像以下

```javascript=
var a = 5
var b = a
a = 10
console.log(b)
```

這時答案會是 5，非常的符合直覺。

上面兩個差別在於「型別」的不同，javascript分為兩種型別

## 「基本型別」(primitives)

包含number、string、boolean、null、undefined、symbol

## 「物件型別」（object）

物件、陣列、函式、日期等

以上的型別分類參考至[你懂 JavaScript 嗎？#4 型別（Types）]( https://cythilya.github.io/2018/10/11/types/)

基本型別是使用「call by value」，也就是說每個宣告的變數都會使用一個記憶體去儲存。
彼此之間是互不干擾的。

```javascript=
var a = 5 //產生記憶體給a，內容為5
var b = a //產生記憶體為b，內容為a的值，也一樣是5
a = 10  //記憶體a的值更新為10
console.log(b) //印出記憶體b的值，一樣是5
```

而物件型別是使用「call by reference」，我們宣告的變數本身本身也會產生一個記憶體給他的值。
而該變數像是生出一個箭頭，指向那個記憶體的位置，也因此叫做「call by reference」，是一個參考的概念。

```javascript=
var a = [ 1, 2, 3 ] //產生記憶體位址，儲存 [ 1, 2, 3 ]這個內容，且a指向此物件內容
var b = a //b不佔記憶體，並且b的值一樣指向a的同樣參照位址，因此一樣是 [ 1, 2, 3 ]
a.push(5) //將5 push進去a參照的陣列(物件)中，因此參照的陣列變成[ 1, 2, 3, 5]
console.log(b) //b參照的位址以發生改變，因此這裡最後的答案一樣是[ 1, 2, 3, 5]
```

由此概念可以知道，我們如果將上面的內容改成下面這樣。

```javascript=
var a = [ 1, 2, 3 ]
var b = a
b.push(5)
console.log(a)
```

我們得到的答案是一模一樣的，都是[ 1, 2, 3, 5]

###### tags: `js學習筆記`
