修復會遺失「this」的函式
重要性:5
以下程式碼中對 askPassword()
的呼叫應檢查密碼,然後根據答案呼叫 user.loginOk/loginFail
。
但它會導致錯誤。為什麼?
修正反白的行,讓所有東西都能正常運作(其他行不要變更)。
function askPassword(ok, fail) {
let password = prompt("Password?", '');
if (password == "rockstar") ok();
else fail();
}
let user = {
name: 'John',
loginOk() {
alert(`${this.name} logged in`);
},
loginFail() {
alert(`${this.name} failed to log in`);
},
};
askPassword(user.loginOk, user.loginFail);
錯誤發生是因為 ask
取得函式 loginOk/loginFail
但沒有物件。
當它呼叫它們時,它們自然會假設 this=undefined
。
讓我們 bind
這個內容
function askPassword(ok, fail) {
let password = prompt("Password?", '');
if (password == "rockstar") ok();
else fail();
}
let user = {
name: 'John',
loginOk() {
alert(`${this.name} logged in`);
},
loginFail() {
alert(`${this.name} failed to log in`);
},
};
askPassword(user.loginOk.bind(user), user.loginFail.bind(user));
現在它運作了。
另一個解決方案可能是
//...
askPassword(() => user.loginOk(), () => user.loginFail());
通常這樣也可以,而且看起來不錯。
不過在更複雜的情況下,它比較不可靠,因為 user
變數可能在呼叫 askPassword
之後,但訪客在回答並呼叫 () => user.loginOk()
之前變更。