Подтвердить что ты не робот

Сохранить ссылку 'this' в обработчике события прототипа javascript

Каков правильный способ сохранить ссылку 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'
};
4b9b3361

Ответ 1

Я нахожу bind() самым чистым решением:

this.bar.onclick = this.ClickEvent.bind(this);

Кстати, другой this очень часто называется that.

Ответ 2

Посмотрите документ 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.

Ответ 3

Проблема с bind заключается в том, что поддерживается только IE9 +.

Функция может быть заполнена с помощью es5-shim, но она не полностью идентична встроенной реализации:

  • Предостережение: связанная функция имеет свойство прототипа.
  • Предостережение: связанные функции не слишком стараются, чтобы вы не манипулировали их свойствами arguments и caller.
  • Предостережение: связанные функции не имеют проверок в call и apply, чтобы избежать выполнения в качестве конструктора.

Другой альтернативой может быть jQuery.proxy:

$(elem).on('click', $.proxy(eventHandler, this));

Это еще более полезно, если вы хотите удалить обработчик событий позже, потому что, когда функция проходит через метод proxy, jQuery генерирует новое значение guid и затем применяет это руководство как к основной функции, так и к результирующей функции прокси-сервера, так что вы можете использовать исходную ссылку функции, чтобы отменить обратный вызов обработчика события, который был проксирован:

$(elem).off('click', eventHandler);

Ответ 4

Другое решение: используйте "функции стрелок", введенные 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
}

Функции функции стрелки @MDN

Edit

Будьте осторожны с этим. Если вы используете его на стороне клиента, и вы не можете быть уверены в возможностях интерпретатора JS, обратите внимание, что старый браузер не распознает функции стрелок (см. CanIUse статистика). Используйте этот метод только в том случае, если вы ЗНАЕТ, что его запустит (недавние браузеры и приложения NodeJS)