Ваша проблема здесь не является точно проблемой закрытия или определения области.Проблема в том, что когда вы присваиваете this.readSuccess
переменной, вы присваиваете саму функцию без какого-либо представления об объекте, которому она изначально принадлежит.
Таким же образом вы можете использовать обычныйв одиночку »и используйте его как метод объекта:
function hello() {
alert("Hello "+this.planet);
}
var planet = "Earth";
hello(); // -> 'Hello Earth'
var Venus = {
planet: "Venus"
};
hello.apply(Venus); // -> 'Hello Venus'
Venus.hello = hello;
Venus.hello(); // -> 'Hello Venus'
И ваша проблема может быть воспроизведена в этом примерепеременная и вызов ее в качестве метода этого .Что может быть сделано с закрытием, как продемонстрировал Пойнти.Поскольку я не знаю, что на самом деле делает SomeAjaxCall, трудно понять, действительно ли потеряно значение this
и действительно ли нужно var obj = this
.Скорее всего, это не так, поэтому вы можете быть в порядке с таким кодом:
var helloVenus = function() { Venus.hello() }
helloVenus(); // -> 'Hello Venus'
В вашем случае это будет ( edit: добавление аргументов, переданных в обработчик):
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall(
"read_some_data",
{ },
function () { this.readSuccess.apply(this, arguments) },
function () { this.readFail.apply(this, arguments) }
);
}
Как отмечалось ранее, в нескольких js-фреймворках предусмотрена функция bind
для упрощения такого рода проблем.Но вам не нужен полный фреймворк только для этого: вот совершенно прекрасный метод Function#bind
, который работает простым javascript:
Function.prototype.bind = function(obj) {
var __method = this;
var args = [];
for(var i=1; i<arguments.length; i++)
args.push(arguments[i]);
return function() {
var args2 = [];
for(var i=0; i<arguments.length; i++)
args2.push(arguments[i]);
return __method.apply(obj, args.concat(args2));
};
}
С помощью Function#bind
вы можете написать:
SomeObject.prototype.refreshData = function()
{
var read_obj = new SomeAjaxCall(
"read_some_data",
{ },
this.readSuccess.bind(this),
this.readFail.bind(this)
);
}