Ответ 1
Вы можете использовать jQuery.proxy()
анонимную функцию, немного неудобно, что "контекст" является вторым параметром.
$("#button").click($.proxy(function () {
//use original 'this'
},this));
Я создал "control" с помощью jQuery и использовал jQuery.extend, чтобы помочь сделать его как OO насколько возможно.
Во время инициализации моего контроля я подключаю различные события кликов, например,
jQuery('#available input',
this.controlDiv).bind('click', this, this.availableCategoryClick);
Обратите внимание, что я pasing 'this' как аргумент данных в методе связывания. Я делаю это, чтобы получить данные, прикрепленные к экземпляру элемента управления, скорее из элемента, который запускает событие click.
Это работает отлично, однако я подозреваю, что есть лучший способ
Используя Prototype в прошлом, я помню синтаксис привязки, который позволял вам контролировать, что в нем было значение 'this'.
Что такое jQuery?
Вы можете использовать jQuery.proxy()
анонимную функцию, немного неудобно, что "контекст" является вторым параметром.
$("#button").click($.proxy(function () {
//use original 'this'
},this));
Мне нравится ваш путь, на самом деле используют аналогичную конструкцию:
$('#available_input').bind('click', {self:this}, this.onClick);
и первая строка this.onClick:
var self = event.data.self;
Мне нравится этот путь, потому что тогда вы получаете как элемент, щелкнутый (как этот), так и объект "this" как сам, без необходимости использования закрытий.
jQuery имеет метод jQuery.proxy
(доступен с версии 1.4).
Пример:
var Foo = {
name: "foo",
test: function() {
alert(this.name)
}
}
$("#test").click($.proxy(Foo.test, Foo))
// "foo" alerted
Я не думаю, что у jQuery есть встроенная функция для этого. Но вы можете использовать вспомогательную конструкцию, как показано ниже:
Function.prototype.createDelegate = function(scope) {
var fn = this;
return function() {
// Forward to the original function using 'scope' as 'this'.
return fn.apply(scope, arguments);
}
}
// Then:
$(...).bind(..., obj.method.createDelegate(obj));
Таким образом, вы можете создавать динамические "функции-обертки" с помощью createDelegate(), которые вызывают метод с данным объектом как область 'this'.
Пример:
function foo() {
alert(this);
}
var myfoo = foo.createDelegate("foobar");
myfoo(); // calls foo() with this = "foobar"
вы можете использовать метод javascript bind:
var coolFunction = function(){
// here whatever involving this
alert(this.coolValue);
}
var object = {coolValue: "bla"};
$("#bla").bind('click', coolFunction.bind(object));
HTML-совместимые браузеры обеспечивают метод привязки на Function.prototype
, который, пожалуй, самый чистый синтаксис и не зависит от структуры, хотя он не встроен в IE до IE 9. (Существует polyfill для браузеров без него.)
На основе вашего примера вы можете использовать его следующим образом:
jQuery('#available input',
this.controlDiv).bind('click', this.availableCategoryClick.bind(this));
(боковое примечание: первый bind
в этом выражении является частью jQuery и не имеет ничего общего с Function.prototype.bind
)
Или использовать немного более сжатый и обновленный jQuery (и устранить путаницу из двух разных типов bind
s):
$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));
jQuery не поддерживает привязки, и предпочтительный способ - использовать функции.
Потому что в Javascript this.availableCategoryClick не означает вызов функции availableCategoryClick для этого объекта, jQuery советует использовать этот предпочтительный синтаксис:
var self = this;
jQuery('#available input', self.controlDiv).bind('click', function(event)
{
self.availableCategoryClick(event);
});
Концепции OO в Javascript трудно понять, функциональное программирование часто проще и читабельнее.
Увидев, что функции меняют область видимости, наиболее распространенным способом является выполнение этого вручную, с чем-то вроде var self = this
.
var self = this
$('.some_selector').each(function(){
// refer to 'self' here
}