Ask losing 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
が要求して () => user.loginOk()
を実行する間に上書きされる可能性のあるようなより複雑な状況の場合に失敗する可能性があります。