en.javascript.info/1-js/6-objects-more/7-bind/5-question-use-bind/solution.md
2015-01-14 10:23:45 +03:00

105 lines
No EOL
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Решение с bind
Ошибка происходит потому, что `ask` получает только функцию, без объекта-контекста.
Используем `bind`, чтобы передать в `ask` функцию с уже привязанным контекстом:
```js
//+ run
"use strict";
function ask(question, answer, ok, fail) {
var result = prompt(question, '');
if (result.toLowerCase() == answer.toLowerCase()) ok();
else fail();
}
var user = {
login: 'Василий',
password: '12345',
loginOk: function() {
alert(this.login + ' вошёл в сайт');
},
loginFail: function() {
alert(this.login + ': ошибка входа');
},
checkPassword: function() {
*!*
ask("Ваш пароль?", this.password, this.loginOk.bind(this), this.loginFail.bind(this));
*/!*
}
};
var vasya = user;
user = null;
vasya.checkPassword();
```
# Решение через замыкание
Альтернативное решение -- сделать функции-обёртки над `user.loginOk/loginFail`:
```js
var user = {
...
checkPassword: function() {
*!*
ask("Ваш пароль?", this.password,
function() { user.loginOk(); }, function() { user.loginFail(); });
*/!*
}
}
```
...Но такой код использует переменную `user`, так что если объект переместить из неё, к примеру, так, то работать он не будет:
```js
var vasya = user; // переместим user в vasya
user = null;
vasya.checkPassword(); // упс будет ошибка, ведь в коде объекта остался user
```
Для того, чтобы избежать проблем, можно использовать `this`. Внутри `checkPassword` он всегда будет равен текущему объекту, так что скопируем его в переменную, которую назовём `self`:
```js
//+ run
"use strict";
function ask(question, answer, ok, fail) {
var result = prompt(question, '');
if (result.toLowerCase() == answer.toLowerCase()) ok();
else fail();
}
var user = {
login: 'Василий',
password: '12345',
loginOk: function() {
alert(this.login + ' вошёл в сайт');
},
loginFail: function() {
alert(this.login + ': ошибка входа');
},
checkPassword: function() {
*!*
var self = this;
ask("Ваш пароль?", this.password,
function() { self.loginOk(); },
function() { self.loginFail(); }
);
*/!*
}
};
var vasya = user;
user = null;
vasya.checkPassword();
```
Теперь всё работает. Анонимные функции достают правильный контекст из замыкания, где он сохранён в переменной `self`.