# JS - 簡單的例子來解釋 apply、call、bind

這三者 為 JavaScript 中常用的函數操作，它們在不同情況下有不同的用途和差異：  
  
用一個簡單的例子來解釋 apply、call、bind，我創建一個 `Yukki`的 object，裡面記錄了`name`, `money`,`atm`, atm 為一個function，可自動幫我存錢到錢包。

```javascript
const Yukki = {
  name: 'Yukki',
  money: 1000,
  atm: function (moeny) {
      this.money += moeny
  }
}
```

當我執行

```javascript
Yukki.atm(1000)

// 會得到以下結果，moeny自動幫我存錢1000，原本只有1000+1000=2000
{name: 'Yukki', money: 2000, atm: ƒ}
```

今天我的女兒，Crystal只有50塊（小孩子可不能給太多錢）

```javascript
const Crystal = {
  name: 'Carystal',
  money: 50
}
```

她收到紅包錢，可她還沒有申請任何ATM，於是她借用了我的ATM帳戶，那麼他可以透過`apply`來使用我的ATM

```javascript
//Yukki.atm.apply(誰要用, [存多少])
Yukki.atm.apply(Crystal, [1000])

// 會得到以下結果
{name: 'Carystal', money: 1050}
```

為了能更方便解釋`apply`與`call`差別，我將 Yukki 的 atm function修改以下：

```javascript
const Yukki = {
  name: 'Yukki',
  money: 1000,
  atm: function (moeny, change) {
      // 除了原本的 money 再加上 change 零用錢
      this.money += (moeny + change)
  }
}
```

### apply

```javascript
const Crystal = {
  name: 'Carystal',
  money: 50
}
// apply，透過array方式傳遞參數
Yukki.atm.apply(Crystal, [100, 50])
// 會得到以下結果
{name: 'Carystal', money: 200}
```

### call

```javascript
const Crystal = {
  name: 'Carystal',
  money: 50
}
// call，參數需要一個一個傳參進去
Yukki.atm.call(Crystal, 100, 50)
// 會得到以下結果
{name: 'Carystal', money: 200}
```

### bind

```javascript
const Crystal = {
  name: 'Carystal',
  money: 50
}
// bind，和 call 一樣透過傳參，但不會馬上執行，而是返回function，等下次調用時才會執行
const CrystalAtm = Yukki.atm.bind(crystal)
CrystalAtm(100, 50)
// 會得到以下結果
{name: 'Carystal', money: 200}
```

除了這個也可以透過 function 來解釋`apply` `call` `bind`三者用法不同

```javascript
function getProfile(name, age) {
	console.log(`Hello,I’m ${name}, ${age} years old.`)
}
// apply，透過array方式傳遞參數
getProfile.apply(null, ['Yukki', 35])

// call，參數需要一個一個傳參進去
getProfile.call(null, 'Yukki', 35)

// bind，和 call 一樣透過傳參，但不會馬上執行，而是返回function，等下次調用時才會執行
const getting = getProfile.bind(null, 'Yukki', 35)
getting()

const person = { name: "Yukki" }

function sayHi(age) {
  return `${this.name} is ${age}`
}

console.log(sayHi.call(person, 21))
console.log(sayHi.bind(person, 21))

會出現什麼？
Yukki is 21
function

因為bind只會返回function，下次調用才會執行
```
