Мы хотим сделать этот проект с открытым исходным кодом доступным для людей во всем мире. Пожалуйста, помогите нам перевести это руководство на другие языки.
вернуться к уроку

Исправьте функцию, теряющую "this"

важность: 5

Вызов askPassword() в приведённом ниже коде должен проверить пароль и затем вызвать user.loginOk/loginFail в зависимости от ответа.

Однако, его вызов приводит к ошибке. Почему?

Исправьте выделенную строку, чтобы всё работало (других строк изменять не надо).

function askPassword(ok, fail) { let password = prompt("Password?", ''); if (password == "rockstar") ok(); else fail(); } let user = { name: 'Вася', loginOk() { alert(`${this.name} logged in`); }, loginFail() { alert(`${this.name} failed to log in`); }, }; askPassword(user.loginOk, user.loginFail);

Ошибка происходит потому, что askPassword получает функции loginOk/loginFail без контекста.

Когда они вызываются, то, естественно, this=undefined.

Используем bind, чтобы передать в askPassword функции loginOk/loginFail с уже привязанным контекстом:

function askPassword(ok, fail) { let password = prompt("Password?", ''); if (password == "rockstar") ok(); else fail(); } let user = { name: 'Вася', loginOk() { alert(`${this.name} logged in`); }, loginFail() { alert(`${this.name} failed to log in`); }, }; askPassword(user.loginOk.bind(user), user.loginFail.bind(user));

Теперь всё работает корректно.

Альтернативное решение – сделать функции-обёртки над user.loginOk/loginFail:

//... askPassword(() => user.loginOk(), () => user.loginFail());

Обычно это также работает и хорошо выглядит. Но может не сработать в более сложных ситуациях, а именно – когда значение переменной user меняется между вызовом askPassword и выполнением () => user.loginOk().