當object中的function作為callback function傳遞給setTimeout時,會發生this指向丟失的問題,今天的文章就來探討要如何解決。
直接舉個例子:
let car = {
color:"blue",
getColor() {
console.log(this.color);
}
}
setTimeout(car.getColor, 1000); // getColor is not defined
這是因為setTimeout中的car.getCar只是call by reference,所以這邊this會預設的指向全域(window),這邊有兩個解決方法:
瀏覽器中的setTimeout與node.js中有些不同,瀏覽器會預設把this指向window,而node.js會把this指向time objetc,但這不影響這邊我們要學習的函數綁定。
不直接以getColor當作callback function,而是在外面包裝一個函數:
let car = {
color:"blue",
getColor() {
console.log(this.color);
}
}
setTimeout(() => car.getColor(), 1000); // blue
在callback function中因為找不到car變數,所以會往上一層執行環境尋找car變數,這樣一來就不會有this丟失的問題了。
但是這個方法存在一個風險,就是今天如果在一秒的時間還沒到之前,car變數發生了變化,會導致getColor無法順利取得,這時候就要使用1.2的方法了。
let car = {
color:"blue",
getColor() {
console.log(this.color);
}
}
setTimeout(() => car.getColor(), 1000); // car.getColor is not a function
car = "new value"
bind是function的一個方法,之後文章會介紹bind、apply與call的比較,簡單來說bind可以綁定function的this值。
let car = {
color:"blue",
getColor() {
console.log(this.color);
}
}
setTimeout(car.getColor.bind(car),1000);
測試一下如果今天改變了car的值:
let car = {
color:"blue",
getColor() {
console.log(this.color);
}
}
setTimeout(car.getColor.bind(car),1000); // blue
car = "new value"