Не ожидайте, что JQuery будет работать на Blackberry вообще. Браузер по умолчанию очень ограничен с точки зрения JavaScript и рендеринга страниц.
Хотя опера на Blackberry может быть другой историей ...
Идентификация этого
является распространенной проблемой в javascript. Он также сломается, если вы попытаетесь создать ярлык для doSomething
:
var do = Bob.doSomething;
do(); // this is no longer pointing to Bob!
Хорошая практика - не полагаться на идентификатор this
. Вы можете сделать это разными способами, но самый простой - явно указать Bob
вместо this
внутри doSomething
. Другой - использовать функцию-конструктор (но тогда вы теряете классный синтаксис объектного литерала):
var createBob = function() {
var that = {};
that.Stuff = '';
that.init = function() {
that.Stuff = arguments[0];
};
that.doSomething = function() {
console.log( that.Stuff );
};
return that;
}
var bob = createBob();
Измените
$('#MyButton').click( Bob.doSomething );
на
$('#MyButton').click( function() { Bob.doSomething() } );
Вы также можете добавить к своему объекту Bob частное поле var that = this
и использовать его везде в членах вместо это
, если вы действительно хотите избежать анонимной функции.
например,
var Bob = new function() {
// Private Fields
var that = this;
// Public Members
this.Stuff = '';
this.init = function() {
that.Stuff = arguments[0];
}
this.doSomething = function() {
console.log( that.Stuff );
}
}
Это не ошибка jQuery, это неотъемлемая часть того, как JavaScript обрабатывает объекты.
В отличие от большинства других объектно-ориентированных языков, 'this' не привязано на уровне каждого метода в JavaScript; вместо этого он определяется исключительно способом вызова функции:
Bob= {
toString: function() { return 'Bob!'; },
foo: function() { alert(this); }
};
Brian= {
toString: function() { return 'Brian!'; },
};
Bob.foo(); // Bob!
Bob['foo'](); // Bob!
Brian.foo= Bob.foo;
Brian.foo(); // Brian! NOT Bob
var fn= Bob.foo;
fn(); // window NOT Bob
То, что вы делаете в случае:
$j('#MyButton').click( Bob.doSomething );
, похоже на последний пример с fn
: вы вызываете функцию doSomething
от Боба и передает его установщику обработчика событий jQuery как чистую функцию: он больше не имеет связи с Бобом или любым другим объектом, поэтому вместо этого JavaScript передает глобальный объект window
. (Это одна из худших особенностей дизайна JavaScript, так как вы можете не сразу заметить, что window
не Bob
, и начать доступ к его свойствам, вызывая странные и сбивающие с толку взаимодействия и ошибки.)
Чтобы запомнить Боба, вы обычно создаете функцию, как в ответе Никита, чтобы сохранить копию «Боб» в замыкании, чтобы ее можно было запомнить в время обратного вызова и используется для вызова реального метода. Однако теперь есть стандартизированный способ сделать это в ECMAScript Fifth Edition:
$j('#MyButton').click( Bob.doSomething.bind(Bob) );
(Вы также можете добавить дополнительные аргументы в вызов bind
, чтобы вызвать doSomething
обратно с ними, то есть удобно.)
Для браузеров, которые еще не поддерживают метод bind () пятой редакции изначально (а на данный момент их большинство), вы можете взломать свою собственную реализацию bind
( библиотека прототипов тоже делает то же самое), что-то вроде:
if (!Object.bind) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
Вы всегда можете попробовать сделать что-то вроде этого:
$j('#MyButton').click(function(event) {
Bob.doSomething(event, this);
});
Теперь doSomething
по-прежнему будет иметь Боб
в качестве this
, и с использованием аргументов функции он будет иметь объект event
и элемент, по которому он был запущен.