JavaScript eval () "синтаксическая ошибка" при разборе строки функции - PullRequest
14 голосов
/ 04 мая 2010

У меня есть немного кода 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 в более специфических пространствах имен.

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

Ответы [ 2 ]

41 голосов
/ 04 мая 2010

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

a = "function(value) { return Math.abs(value);}";
b = eval("("+a+")");
b(-1);
5 голосов
/ 31 января 2012

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

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

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

function foo(arg) {}

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

var funcExpr = function foo(arg) {};

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

Так что это недопустимая декларация, потому что отсутствует ее имя:

function (arg) {}

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

var funcExpr = function(arg) {};
...