iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

JavaScript學習日記系列 第 11

JavaScript學習日記 : Day11 - 函數綁定

當object中的function作為callback function傳遞給setTimeout時,會發生this指向丟失的問題,今天的文章就來探討要如何解決。

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

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"

上一篇
JavaScript學習日記 : Day10 - This
下一篇
JavaScript學習日記 : Day12 - Event Loop
系列文
JavaScript學習日記30

尚未有邦友留言

立即登入留言