Вход

Просмотр полной версии : Правильная перегрузка метода-обработчика события


Novascriptum
13.07.2014, 22:16
Всем доброго времени!
Пусть имеется некая абстрактная функция-конструктор:


function AbstractObj(){
var me = this;
this.param = 'some param';
this.a = function(e){
console.log(me);
}
this.b = function(){
$('some element').click(this.a); //Здесь может быть любой код, который ставит какому-то событию обработчик "this.a"
}
}


Теперь есть некий кусок кода, который создает объект и пытается переопределить метод-обработчик:

var com = new AbstractObj();
com.a = function(e){
console.log('Overrided:');
console.log(me);
}
com.b();

В результате при возникновении нашего события, описанного в методе b, получим сообщение об ошибке: "Uncaught ReferenceError: me is not defined".
Значит, новая функция "a" не имеет доступа к внутренним переменным AbstractObj. Попробовал замыкания. Добавим в AbstractObj метод для перегрузки:


function AbstractObj(){
//Все то же самое плюс новая функция
this.Override = function(key, value){
this[key] = (function(){
return value;
})();
}
}


Используем:

var com = new AbstractObj();
com.Override('a', function(e){
console.log('Overrided:');
console.log(me);
});
com.b();


В результате получаем ту же ошибку. Вопрос: как сделать, чтобы из нового метода был доступ к переменным вроде "me"?

Aetae
13.07.2014, 22:31
Никак.
Либо this.me = me, либо this.getMe=function(){return me}.

Novascriptum
13.07.2014, 22:33
Видимо, я проблему обозначил не совсем точно.
Метод-обработчик события отличается от обычного метода тем, что this в нем указывает на объект события, а не на родительский объект метода.
Проблема как раз в том, чтобы получить доступ к этому this родительского объекта. Чтобы хотя бы узнать this.param. В новом методе "a" теряется всякая связка с родительским объектом и его даже публичными свойствами.

Aetae
13.07.2014, 22:39
obj.method.bind(this). - привязывает конкретный this к функции.
Полифил для старых браузеров(с mdn):if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}

var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments) ));
};

fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();

return fBound;
};
}