Ответ 1
Я нахожу bind()
самым чистым решением:
this.bar.onclick = this.ClickEvent.bind(this);
Кстати, другой this
очень часто называется that
.
Каков правильный способ сохранить ссылку javascript this
в обработчике событий, хранящемся внутри прототипа объекта? Я хотел бы держаться подальше от создания временных тем, таких как "_this" или "this", и я не могу использовать фреймворк, например jQuery. Я видел, как много людей говорили об использовании функции "привязки", но не знали, как реализовать его в моем сценарии.
var Example = function(foo,bar){
this.foo = foo;
this.bar = bar;
};
Example.prototype.SetEvent = function(){
this.bar.onclick = this.ClickEvent;
};
Example.prototype.ClickEvent = function(){
console.log(this.foo); // logs undefined because 'this' is really 'this.bar'
};
Я нахожу bind()
самым чистым решением:
this.bar.onclick = this.ClickEvent.bind(this);
Кстати, другой this
очень часто называется that
.
Посмотрите документ MDN на bind
: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Используя эту функциональность, вы можете изменить область действия (что this
):
Example.prototype.SetEvent = function(){
this.bar.onclick = this.ClickEvent.bind(this);
};
Помните, однако, что это новое дополнение к EMCA и, следовательно, может не поддерживаться во всех пользовательских агентах. В документе MDN имеется ссылка на pollyfill.
Проблема с bind
заключается в том, что поддерживается только IE9 +.
Функция может быть заполнена с помощью es5-shim
, но она не полностью идентична встроенной реализации:
- Предостережение: связанная функция имеет свойство прототипа.
- Предостережение: связанные функции не слишком стараются, чтобы вы не манипулировали их свойствами
arguments
иcaller
.- Предостережение: связанные функции не имеют проверок в
call
иapply
, чтобы избежать выполнения в качестве конструктора.
Другой альтернативой может быть jQuery.proxy
:
$(elem).on('click', $.proxy(eventHandler, this));
Это еще более полезно, если вы хотите удалить обработчик событий позже, потому что, когда функция проходит через метод proxy
, jQuery генерирует новое значение guid и затем применяет это руководство как к основной функции, так и к результирующей функции прокси-сервера, так что вы можете использовать исходную ссылку функции, чтобы отменить обратный вызов обработчика события, который был проксирован:
$(elem).off('click', eventHandler);
Другое решение: используйте "функции стрелок", введенные ES6. У них есть особенность, чтобы не изменять контекст, IE, на что указывает this
. Вот пример:
function Foo(){
myeventemitter.addEventListener("mousedown", (()=>{
return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
})());
}
Foo.prototype.myinstancefunction = function(event){
// Handle event in the context of your Object
}
Edit
Будьте осторожны с этим. Если вы используете его на стороне клиента, и вы не можете быть уверены в возможностях интерпретатора JS, обратите внимание, что старый браузер не распознает функции стрелок (см. CanIUse статистика). Используйте этот метод только в том случае, если вы ЗНАЕТ, что его запустит (недавние браузеры и приложения NodeJS)