Выражение Eval-функции - PullRequest
0 голосов
/ 08 мая 2019

Пока я ожидал, что этот код

var  a = eval("function() { return 1; }");

console.log(a());

напечатает '1' в консоли, я получаю синтаксическую ошибку Uncaught SyntaxError: Unexpected token (.Что я здесь не так делаю?


Я работаю с платформой, которая позволяет определять функции javascript в конфигурации, поэтому у меня нет другого выбора, кроме как использовать eval.

Ответы [ 4 ]

4 голосов
/ 08 мая 2019

Ключевое слово function в Javascript неоднозначно: оно может начинать объявление функции (оператор) или литерал функции (выражение).Когда function встречается в позиции оператора, синтаксический анализатор добровольно предпочитает объявление над выражением.Поскольку eval ожидает оператор, это делает ваш код недействительным - имя функции требуется для объявлений.Вы можете либо указать имя:

eval('function foo() {...}')

, либо принудительно заставить анализатор перейти в режим выражения

foo = eval('( function () {...} )')

, в этом случае function будет считаться литералом.

Это в основном та же история, что и с {}, который может быть либо блоком, либо литералом объекта.Что-то вроде eval('{1:2}') завершится ошибкой по той же причине (оператор предпочтительнее выражения).

2 голосов
/ 08 мая 2019

Проблема в том, что у вас есть объявление функции , для которого требуется имя. Для справки это объявление функции

function myFunc() { console.log("executed") } //<-- declaration

myFunc(); //<-- execution

То, что вы ожидаете получить , является неназванным выражением функции

var myFunc = function() { console.log("executed") }
//expression ^------------------------------------^

myFunc(); //<-- execution

Или для действительно неназванной функции, которую вы не назначаете переменной, вы можете иметь IIFE

// ( <-- brackets around the expression --> )
(            function() { console.log("executed") } )()
//expression ^------------------------------------^  ^^
//execution  ----------------------------------------^^

Однако в JavaScript автономный оператор, начинающийся с ключевого слова function, будет обрабатываться как объявление , а если у него нет имени, он недопустим.

Однако вы можете обойти это, заключив выражение в скобки, чтобы сделать его приемлемым для синтаксического анализатора.

//brackets    v--------------------------v
var a = eval("( function() { return 1; } )");
//              ^----------------------^ function expression
console.log(a());
1 голос
/ 08 мая 2019

Вы не можете смешивать объявления функций и выражения функций таким образом.Вы должны сделать полное объявление или выражение внутри eval().

 eval("function a() { return 1; }");
 console.log(a());

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

 eval("var a = function() { return 1; }");
 console.log( a() );

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

Ни один из них не должен использоваться, если есть альтернативы.Наиболее распространенной альтернативой является использование new Function();.

var a = new Function( 'return 1;' );
console.log( a() );

Это дает тот же конечный результат и немного безопаснее, чем использование eval().

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

1 голос
/ 08 мая 2019

Поскольку комментарии на 100% верны, что функция должна содержать имя или должна быть инициализирована как анонимная функция, решение вашей проблемы есть.

Если вы хотите создать функцию по тексту, вы можете использовать конструктор функции

new Function ([arg1[, arg2[, ...argN]],] functionBody)

Для получения дополнительной информации смотрите https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function

...