2015-02-06 3 views
1

У меня есть объект JS, и одна из его прототипов - это обработчик событий для щелчка. Когда эта функция вызывается, объекту this присваивается элемент, к которому привязан клик. Я бы хотел, чтобы this был экземпляром объекта, к которому принадлежит функция. Возможно ли это, и если да, то как мне это сделать? Решения с или без jQuery приемлемы для меня, хотя я уверен, что остальная часть SO оценит чистое решение JS.Как предотвратить «это» от отскока обработчиками событий

Я пробовал binding the function to this, и он привязан к окну, а не к экземпляру объекта.

Пример того, что я хочу: В this demo (код дублируется ниже), я хочу, предупреждение, которое говорит «Барк», когда кнопка нажата.

var Dog = function() { 
    this.sound = "Bark"; 
} 

Dog.prototype = { 
    sayHello: function (e) { 
     if (typeof this.sound == "undefined") { 
      alert("I don't know what sound I should make!\n" + this); 
     } else { 
      alert(this.sound); 
     } 
    } 
} 

var d = new Dog(); 
var elem = document.getElementById("click"); 
elem.addEventListener("click", d.sayHello); 

ответ

2

Если вы всегда намерены для функции, которая будет вызываться с собственным контекстом, выполняйте привязку, когда вместо этого выполняется конструктор:

var Dog = function() { 
    this.sound = "Bark"; 
    this.sayHello = this.sayHello.bind(this); 
} 

http://jsfiddle.net/04ykpsx1/1/

Нечто подобное _.bindAll может уменьшить шаблонное для вас.

Это лучший подход, чем заставить ваших абонентов всегда вызывать функцию с помощью .bind, потому что им не нужно так глубоко понимать ваш класс.

+0

Мне нравится этот метод гораздо больше, потому что он не требует от меня связывания каждый раз, и из-за того, что вы сказали в последнем предложении о том, как вызывающий должен не знать, как работает этот метод, и что им нужно что-то связать. Благодаря! –

+0

Да, это мое мнение, что это «деталь реализации» вашего класса. Никто не должен заботиться о том, используете ли вы эту функцию внутри функции; он должен просто работать, как ожидает абонент. Случаи, когда ваш класс предоставляет псевдостатическую функцию, предназначенную для вызова в нескольких контекстах, - это когда вызывающему нужно «вручную» связывать. – Interrobang

4

Вы можете использовать .bind() так:

elem.addEventListener("click", d.sayHello.bind(d)); 

Ручной способ сделать это с вашей собственной функции:

elem.addEventListener("click", function(e) { 
    return d.sayHello(); 
}); 
Смежные вопросы