ItIron2021
Javascript
昨天我們用了最~簡單的層面講解了什麼是this,是的,那只是很基本的解釋,足夠你應付面試的題目但我還是會建議多下一點功夫了解! 今天我們就針對this來做個簡單的應用題目吧!
請解釋call, bind & apply的差異
防雷防雷,我英要出第三部劇場版囉~!
還記得我們昨天有談過有幾種常見的情況會改變this的指向嗎? 這就是最為常見的一種了,實際上這個問題並不困難,他們三種都是呼叫函數的方法,只是透過這三種方法呼叫函數時你可以改變該函數中this的指向而已。
我們一般會分成兩組討論,call & apply一組,bind自己一組,先看比較簡單的吧!
call & apply
call & apply在使用上基本上是完全相同的,唯一的差別在於傳入參數的方法不同
call傳入參數時需要一個一個傳,apply則是以陣列方式傳入參數,我們一樣看個簡單的例子吧!
const obj= {name: 'Danny'}
function greet(a, b) {
return `${a}, ${this.name}, ${b}`
}
console.log(greet.call(obj,'Hello','How are you?'))
console.log(greet.apply(obj,['Hello','How are you?']))
// 兩者輸出結果會完全相同
Hello, Danny, How are you?
上方的例子你可以看到,兩個方法接收的第一個參數都是你想讓呼叫的函數this指向誰,第二個參數之後則是你要傳入該函數的參數,apply以陣列的方式接收傳入的參數,兩者的差別僅此而已!
你可能會覺得call有點眼熟,沒錯,我們當時在談論如何檢查變數型別的問題時祭出的最後殺招就是呼叫掛在Object下方的toString方法!
Object.prototype.toString.call([]) // '[object Array]'
bind
接著就是邊緣人bind,他與前兩者不同,並不是直接呼叫函數,而是回傳一個綁定好this的函數,以上面的例子來看,用bind改寫就會是下方的寫法。
const obj= {name: 'Danny'}
function greet(a, b) {
return `${a}, ${this.name}, ${b}`
}
const bound = greet.bind(obj)
console.log(bound('Hello', 'How are you?'))
// 還是那個輸出結果
Hello, Danny, How are you?
需要注意的是,一旦被綁訂過的函數(以上方的範例來說就是greet函數),後續你再做其他的綁定就會完全無效,具體的原因請參考本日的參考文章! 除此之外,這三者的差別是不是很簡單就能講出來呢?
call、bind & apply,this
本文章同步發布於個人部落格,有興趣的朋友也可以來逛逛~!