# <font class="h2">`call`, `apply`, `bind`運用</font>
###### tags: `javascript`
<style>
.h2 {
background: linear-gradient(135deg,#fff,#537479) ;
color: #537479;
display:block;
padding: 6px 5px;
border-radius: 4px;
}
.h3 {
background: linear-gradient(180deg,#fff 50%,#c9d5d4) ;
color: #537479;
display:block;
padding: 6px 5px;
border-bottom: 3px solid #537479;
}
.h4 {
color: #537479;
font-weight:bold;
font-size:1.1em;
}
</style>
### <font class="h3">範例一</font>

newBook函式在這裡是regular function call,所以this會指向undefined
<br><br>
### <font class="h4">➤使用call:</font>
```javascript
const luftansa = {
airline: 'Lufthansa',
iataCode: 'LH',
book(flightNum, name) {
console.log(`${name} 訂了${this.airline}的機票${this.iataCode}${flightNum}`)
}
}
const eurowings = {
airline: 'Eurowings',
iataCode: 'EW'
}
const newBook = luftansa.book
newBook.call(luftansa, 239, 'Mary Cooper') //Mary Cooper 訂了Lufthansa的機票LH239
newBook.call(eurowings, 23, 'Sarah Williams') //Sarah Williams 訂了Eurowings的機票EW23
```
<br><br>
### <font class="h4">➤使用apply:</font>
```javascript
const luftansa = {
airline: 'Lufthansa',
iataCode: 'LH',
book(flightNum, name) {
console.log(`${name} 訂了${this.airline}的機票${this.iataCode}${flightNum}`)
}
}
const nowBook = luftansa.book
const flightData = [583, 'George Cooper']
nowBook.apply(luftansa, flightData) //George Cooper 訂了Lufthansa的機票LH583
```
<br><br>
### <font class="h4">➤使用bind:</font>
```javascript
const luftansa = {
airline: 'Lufthansa',
iataCode: 'LH',
book(flightNum, name) {
console.log(`${name} 訂了${this.airline}的機票${this.iataCode}${flightNum}`)
}
}
const eurowings = {
airline: 'Eurowings',
iataCode: 'EW'
}
const nowBook = luftansa.book
const bookLH = nowBook.bind(luftansa)
const bookEW = nowBook.bind(eurowings)
bookLH(23,'Steven Williams') //Steven Williams 訂了Lufthansa的機票LH23
bookEW(583, 'George Cooper') //George Cooper 訂了Eurowings的機票EW583
```
<br><br>
### <font class="h4">➤bind可以預設定好參數:</font>
```javascript
const luftansa = {
airline: 'Lufthansa',
iataCode: 'LH',
book(flightNum, name) {
console.log(`${name} 訂了${this.airline}的機票${this.iataCode}${flightNum}`)
}
}
const eurowings = {
airline: 'Eurowings',
iataCode: 'EW'
}
const book = luftansa.book
const bookLH23 = book.bind(luftansa, 23)
bookLH23('Steven Williams') //Steven Williams 訂了Lufthansa的機票LH23
bookLH23('George Cooper') //George Cooper 訂了Lufthansa的機票LH23
```
<br><br><br>
### <font class="h3">bind與監聽事件的運用:</font>
```htmlembedded
<button class="buy">買新飛機</button>
```
```javascript
const luftansa = {}
luftansa.planes = 300
luftansa.buyPlane = function () {
console.log(this)
this.planes++
console.log(this.planes)
}
document.querySelector('.buy').addEventListener('click', luftansa.buyPlane)
```

<br>
### 使用bind:
這裡監聽事件是要傳遞一個函式進去,而不是呼叫,所以不使用call而是使用bind
```javascript
const luftansa = {}
luftansa.planes = 300
luftansa.buyPlane = function () {
console.log(this)
this.planes++
console.log(this.planes)
}
document.querySelector('.buy')
.addEventListener('click', luftansa.buyPlane.bind(luftansa))
```

<br><br><br><br>
### <font class="h3">bind作預設值的運用:</font>
```javascript
const addTax = (rate,value) =>value+value*rate
const addVAT = addTax.bind(null,0.23)
console.log(addVAT(100)) //123
console.log(addVAT(23)) //28.29
```
### 也可以使用閉包:
```javascript
const addTax = function(rate){
return function(value){
return value + value*rate
}
}
const addVAT = addTax(0.23)
console.log(addVAT(100)) //123
console.log(addVAT(23)) //28.29
```