修复一个丢失“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()
之前发生改变。