Как реорганизовать эту анонимную функцию Javascript?

У нас есть эта анонимная функция в нашем коде, которая является частью параметров объекта jQuery Ajax и которая использует некоторые переменные из функции, из которой она вызвана.

this.invoke = function(method, data, callback, error, bare) {
      $.ajax({
        success: function(res) {
            if (!callback) return;

            var result = "";
            if (res != null && res.length != 0)
                var result = JSON2.parse(res);

            if (bare)
            { callback(result); return; }

            for (var property in result) {
                callback(result[property]);
                break;
            }
        }
   });
}

Я опустил дополнительный код, но вы поняли эту идею. Код работает отлично, но он протекает 4 Kbs при каждом вызове в IE, поэтому я хочу реорганизовать его, чтобы превратить анонимную функцию в именованный, например this.onSuccess = function (res) {..}.

Проблема в том, что эта функция использует переменные из this.invoke(..), поэтому я не могу просто взять ее за пределы своего тела. Как правильно отредактировать этот код, чтобы он не использовал анонимные функции и родительские функциональные переменные?

Обновление. Я собираюсь создать отдельный объект, инициализируя его с теми же параметрами и передать его функцию onSuccess в качестве параметра для объекта jQuery Ajax. Хотя я подозреваю, что он все равно будет утечка памяти.

Обновление 2.. Я нашел несколько ссылок, предполагающих, что фактическая утечка может быть вызвана jQuery. Простой jQuery Ajax вызывает утечку памяти в Internet Explorer Утечка памяти с использованием запросов jQuery Ajax

Тем не менее было хорошо найти способ рефакторинга этого.

Обновить 3. Я буду ждать более общего решения, прежде чем принимать ответ.

Ответ 1

Вы можете добавить дополнительные параметры к запросу ajax, к которому можно получить доступ в обратном вызове успеха:

this.invoke = function(method, data, callback, error, bare) {
    $.ajax({
        success: onSuccess,
        invokedata: {
         callback: callback,
         bare: bare
        }
    });
};

var onSuccess = function(res) {
    var callback = this.invokedata.callback,
        bare = this.invokedata.bare;
    if (!callback) return;

    var result = "";
    if (res != null && res.length != 0)
        var result = JSON2.parse(res);

    if (bare){
        callback(result); 
        return;
    }

    for (var property in result) {
        callback(result[property]);
        break;
    }
}

Ответ 2

+1 для отличного, отличного вопроса - я чувствую вашу боль - это действительно прекрасно учтено, как есть.

Одно предложение (возможно, это то, что вы подразумеваете под своим обновлением)... определите оболочку для onSuccess и верните функцию, которую вы хотите назначить. Затем вызовите внешнюю функцию и назначьте ее опции "success", передав нужные значения. Эти значения будут предварительно назначены переменным во внутренней функции. На самом деле не уверен, что это поможет - у вас все еще есть анонимная функция, но стоит попробовать

this.invoke = function(method, data, callback, error, bare) {
    $.ajax({
        success: onSuccess(callback, bare);
    });
};

var onSuccess = function(callback, bare) {
     return function() {
        if (!callback) return;

        var result = "";
        if (res != null && res.length != 0)
            var result = JSON2.parse(res);

        if (bare)
        { callback(result); return; }

        for (var property in result) {
            callback(result[property]);
            break;
        }
     }
}