Arreglar una función que perdió "this"
La llamada a askPassword()
en el código a continuación debe verificar la contraseña y luego llamar a user.loginOk/loginFail
dependiendo de la respuesta.
Pero lleva a un error. ¿Por qué?
Arregle la línea resaltada para que todo comience a funcionar correctamente (no se deben cambiar otras líneas).
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);
El error se produce porque askPassword
obtiene las funciones loginOk/loginFail
sin el objeto.
Cuando las llama, estas asumen this = undefined
.
Vamos a usar bind
para enlazar el contexto:
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));
Ahora funciona.
Una solución alternativa podría ser:
//...
askPassword(() => user.loginOk(), () => user.loginFail());
En general, funciona y se ve bien.
Aunque esto es menos confiable, si puede darse el caso en donde user
cambia después de llamar a askPassword
, pero antes de que el visitante responda y se invoque () => user.loginOk()
.