Закрытие JavaScript - Eval () и захват переменных в области видимости Eval () - PullRequest
3 голосов
/ 21 сентября 2011

Мой вопрос касается JavaScript-замыканий и функции Eval ().

У меня есть некоторый код, похожий на этот, есть также другой код, связанный с плагином jQuery, который не показан.При необходимости я могу обновить вопрос, добавив больше кода.

var _CurrentDataRowIndex = 1;

function LoadParsedRowTemplate(rowData, type) {

    var result;
    var asyncbinder = /&\{[\S\s]*?}&/g;

        while ((result = asyncbinder.exec(template)) != null) {
            replacement = eval("$.fn.ScreenSetup." + result[0].substring(2, result[0].length - 3) + ", rowData, " + _CurrentDataRowIndex + ")");
            template = template.replace(result[0], "AsyncBind!!");
            asyncbinder.lastIndex = 0;
        }

}

function AsynchronousBind(asyncFunc, args, rowData, rowIndex) {

    var watchTimer;

    asyncFunc.apply(this, Array.prototype.slice.call(args.FunctionArgs, 0));

    watchTimer = setInterval(function () {

        if (args.finished) {
            clearTimeout(watchTimer);
        }
        else {
            try {
                console.log("watching the async function for a return on row: " + rowIndex);
            }
            catch (err) {
            }
        }

    }, 1000);

}

Eval не захватывает rowData и _CurrentDataRowIndex, оба не определены при вызове функции AsynchronousBind.Как eval работает с замыканиями?Мне интересно, почему аргументы rowData и rowIndex не определены в AsynchronousBind.

Редактировать:

Я знаю о противоречивой природе eval (), однако это для приложения за брандмауэром, и я добавляю в плагинмы уже писали, что использует eval для разбора шаблонов, содержащих HTML и JavaScript.

Вот пример строки, передаваемой в eval ():

 "$.fn.ScreenSetup.AsyncBind( _CurrentDataRow.isPromotionAvailable, {
     'FunctionArgs': {'doAsync' : true, 
                      'finished' : false}, 
      'Property': 'isPromotionAvailable()', 
      'ControlType': 'TextBox', 
      'ControlIdPrefix': 'promoAvail'}, rowData, 3)"

Редактировать(Исправлено):

Понял, что когда я добавил rowData и rowItem II забыл изменить следующее в моем плагине:

var asyncMethods = {
    AsyncBind: function (func, args) { return AsynchronousBind(func, args) }
}

Должно было быть:

var asyncMethods = {
    AsyncBind: function (func, args, rowData, rowIndex) { return AsynchronousBind(func, args, rowData, rowIndex) }
}

Обновление исправило неопределенную ссылку в функции AsyncBind.

1 Ответ

5 голосов
/ 21 сентября 2011

Понимание eval scope - интересная статья.Это показывает, что область применения несовместима между браузерами.Если вы должны использовать eval, вы должны быть осторожны, чтобы рассчитывать только на то, что он находится в глобальной области, и не используйте повторно имена глобальных переменных в вашей локальной области, если она оценивается локально.Не использую Eval.Возможно, у вас есть другие варианты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...