Передача контекста в обработчики событий в jQuery

Обычно для того, чтобы this указывал не на тот объект, который вызвал событие, а на тот, из которого навесили обработчик, делается примерно так:

var obj = {
  message: 'Hullo!',
  init: function() {
    var this_ = this;
    $('.button').click(function(){ this_.handler(42) });
  },
  handler: function(num) {
    alert(this.message + "\n" + num);
  }
};
obj.init();

В jQuery есть правильный способ это сделать — метод jQuery.proxy():

$('.button').click($.proxy(function(){ this.handler(42) }, this));

Однако, если в метод нужно передать параметры, то короче от этого не станет, всё равно придётся создавать замыкание. Вот если бы параметров не было, получилось бы просто и красиво:

$('.button').click($.proxy(this.handler, this));

Но есть и более краткий способ передать и контекст, и параметры — через параметр data методов eventname():

$('.button').click(this, function(e){ e.data.handler(42) });

К сожалению, этот способ работает начиная с jQuery 1.4.3, в более раниих версиях нужно использовать bind(), что несколько длиннее и не так красиво.

Дополнение. Когда-нибудь наступит светлое будущее, и можно будет пользоваться нативным методом bind. Вот так:

$('.button').click(this.handler.bind(this));

Или с параметром:

$('.button').click(this.handler.bind(this, 42));

Уже сейчас метод bind работает в последних версиях всех браузеров (включая IE9). Полифил для старых браузеров есть на MDN по ссылке выше. А если вы используете Modernizr, то полифил у вас уже есть.

Вы можете улучшить этот пост, отредактировав его на Гитхабе.

Обо мне

Я живу в Берлине и работаю фронтенд-разработчиком в Хире, а в свободное время фотографирую, пишу, глажу своих собак и пью кофе.

Читайте обо мне на моём сайте и подпишитесь на мой блог о фотографии и твитер.