iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
自我挑戰組

菜鳥前端修練之旅系列 第 15

Day 15 | call(), apply(), bind()

  • 分享至 

  • xImage
  •  

這篇來看看能改變 JavaScript 中 this 的三種方法:就是標題的 call()apply()bind()

接下來會使用下面的例子:

const person = {
  name: 'Peter'
}

function sayHi(){
  console.log(`Hi, ${this.name}`)
}

sayHi() // Hi, Peter

透過這三種方法,讓 sayHi() 這個函式改變 this 指向,印出 Hi, Peter。

bind 用法

先上語法:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

使用 bind 需要注意:

  • bind 會建立一個新的函式,需要額外執行。
  • this 會綁定到第一個參數。

實際寫法為:

const sayHiPeter = sayHi.bind(person)
sayHiPeter() // Hi, Peter

或是直接接到函式後方:

const sayHiPeter = function sayHi(){
  console.log(`Hi, ${this.name}`)
}.bind(person)()

使用參數

bind 可以綁定傳入函式的參數。 可以選擇將參數寫死,或是自行傳入,先將程式碼改一下:

const person = {
  name: 'Peter'
}

// 需要傳入 age 和 sex 兩個參數
function sayHi(age, sex){
  console.log(`Hi, ${this.name}`)
  console.log(age, sex)
}

方法 1, 寫死參數

const sayHiPeter = sayHi.bind(person, 12, "male")
sayHiPeter() 
// 印出 peter, 12, male

方法 2,自行帶入

const sayHiPeter = sayHi.bind(person)
sayHiPeter(12, "male")
// 印出 peter, 12, male

兩者差別在於,使用方法 1 後,不論之後如何更改值都無法被改變。

apply & call 用法

而這兩個與 bind 的主要差異為:call & apply 會直接執行函式。

兩者的語法為:

// apply()
fun.apply(thisArg, [argsArray])

// call()
fun.call(thisArg, arg1, arg2, ...)
  • 第一個參數為 this 指向。
  • applycall 的差異在於傳入的函式參數不一樣,apply 需要傳入陣列。

使用 call

sayHi.call(person, 12, "male")
// 印出 peter, 12, male

使用 apply(傳遞陣列):

sayHi.apply(person, [12, "male"])
// 印出 peter, 12, male

實際運用

來嘗試改變物件中函式的指向:

const fruit = {
  fruitName: 'apple',
  getFruitName: function () {
    console.log(this.fruitName)
  }
}

fruit.getFruitName() 
// 印出 apple

這時候再建立一個 someFruit,並把原本 fruit 中的函式指向它。

const someFruit = {
  fruitName: 'banaba'
}

fruit.getFruitName.call(someFruit)
// banana

參考資料


上一篇
Day 14 | JS 中的原型鍊
下一篇
Day 16 | 立即函式 IIFE
系列文
菜鳥前端修練之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言