Подтвердить что ты не робот

JavaScript eval() "синтаксическая ошибка" при разборе строки функции

У меня есть код JavaScript, который указан в файле конфигурации на стороне сервера. Поскольку я не могу указать функцию JavaScript на языке конфигурации (Lua), у меня есть она как строка. Сервер возвращает строку в некотором JSON, и я интерпретирую ее с помощью функции очистки:

parse_fields = function(fields) {
    for (var i = 0; i < fields.length; ++i) {
        if (fields[i].sortType) {
            sort_string = fields[i].sortType;
            fields[i].sortType = eval(sort_string);
        }
        return fields;
    }
}; 

В принципе, он просто оценивает sortType, если он существует. Проблема в том, что Firebug сообщает об ошибке "Синтаксическая ошибка" в строке eval(). Когда я запускаю те же шаги в консоли Firebug, он работает без проблем, и я могу выполнить функцию, как я ожидаю. Я пробовал несколько разных вариантов: window.eval вместо обычного eval, сохраняя sortType, как я уже говорил выше, и пробовал небольшие изменения в строке.

Образец значения fields[i].sortType равен "function(value) { return Math.abs(value); }". Здесь тестирование, которое я сделал в консоли Firebug:

>>> sort_string
"function(value) { return Math.abs(value); }"
>>> eval(sort_string)
function()
>>> eval(sort_string)(-1)
1

и сама ошибка в Firebug:

syntax error
[Break on this error] function(value) { return Math.abs(value); }

Последний бит, который может быть уместным, заключается в том, что все это завернуто в функцию Ext JS onReady() с изменением пространства имен Ext.ns вверху. Но я предположил, что window.eval будет вызывать глобальный eval, независимо от любого возможного eval в более конкретных пространствах имен.

Любые идеи приветствуются.

4b9b3361

Ответ 1

Чтобы сделать то, что вы хотите, оберните свою строку в круглые скобки:

a = "function(value) { return Math.abs(value);}";
b = eval("("+a+")");
b(-1);

Ответ 2

Скобки необходимы, потому что они заставляют вещь внутри них оцениваться в контексте выражения, где она должна быть функциональным выражением.

Без круглых скобок она может быть объявлением функции, и кажется, что она иногда разбирается в этом случае - это может быть источником нечетного/непоследовательного поведения, которое вы описываете.

Сравните это объявление функции:

function foo(arg) {}

с помощью этой функции-выражения:

var funcExpr = function foo(arg) {};

Это также должно быть выражение функции, если оно не имеет имени. Объявление функций требует имен.

Итак, это не допустимое объявление, поскольку оно не имеет имени:

function (arg) {}

но это действительное анонимное выражение функции:

var funcExpr = function(arg) {};