Как можно динамически создать функцию с кодом из произвольной строки js
Перейти к содержимому

Как можно динамически создать функцию с кодом из произвольной строки js

  • автор:

Eval: выполнение строки кода

Встроенная функция eval позволяет выполнять строку кода.

let result = eval(code);
let code = 'alert("Привет")'; eval(code); // Привет

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

Результатом eval будет результат выполнения последней инструкции.

let value = eval('1+1'); alert(value); // 2
let value = eval('let i = 0; ++i'); alert(value); // 1

Код в eval выполняется в текущем лексическом окружении, поэтому ему доступны внешние переменные:

let a = 1; function f() < let a = 2; eval('alert(a)'); // 2 >f();

Значения внешних переменных можно изменять:

let x = 5; eval("x = 10"); alert(x); // 10, значение изменено

В строгом режиме у eval имеется своё лексическое окружение. Поэтому функции и переменные, объявленные внутри eval , нельзя увидеть снаружи:

// напоминание: режим 'use strict' включён по умолчанию во всех исполняемых примерах eval("let x = 5; function f() <>"); alert(typeof x); // undefined (нет такой переменной) // функция f тоже невидима

Без use strict у eval не будет отдельного лексического окружения, поэтому x и f будут видны из внешнего кода.

Использование «eval»

В современной разработке на JavaScript eval используется весьма редко. Есть даже известное выражение – «eval is evil» («eval – это зло»).

Причина такого отношения достаточно проста: давным-давно JavaScript был не очень развитым языком, и многие вещи можно было сделать только с помощью eval . Но та эпоха закончилась более десяти лет назад.

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

Пожалуйста, имейте в виду, что код в eval способен получать доступ к внешним переменным, и это может иметь побочные эффекты.

Минификаторы кода (инструменты, используемые для сжатия JS-кода перед тем, как отправить его конечным пользователям) заменяют локальные переменные на другие с более короткими именами для оптимизации. Обычно это безопасная манипуляция, но не тогда, когда в коде используется eval , так как код из eval может изменять значения локальных переменных. Поэтому минификаторы не трогают имена переменных, которые могут быть доступны из eval . Это ухудшает степень сжатия кода.

Использование внутри eval локальных переменных из внешнего кода считается плохим решением, так как это усложняет задачу по поддержке такого кода.

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

Если код внутри eval не использует внешние переменные, то вызывайте его так – window.eval(. ) :

В этом случае код выполняется в глобальной области видимости:

Строки

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Есть ряд улучшений и новых методов для строк.

Начнём с, пожалуй, самого важного.

Строки-шаблоны

Добавлен новый вид кавычек для строк:

let str = `обратные кавычки`;

Основные отличия от двойных «…» и одинарных ‘…’ кавычек:

    В них разрешён перевод строки. Например:

alert(`моя многострочная строка`);
'use strict'; let apples = 2; let oranges = 3; alert(`$ + $ = $`); // 2 + 3 = 5

Функции шаблонизации

Можно использовать свою функцию шаблонизации для строк.

Название этой функции ставится перед первой обратной кавычкой:

let str = func`моя строка`;

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

'use strict'; function f(strings, . values) < alert(JSON.stringify(strings)); // ["Sum of "," + "," =\n ","!"] alert(JSON.stringify(strings.raw)); // ["Sum of "," + "," =\\n ","!"] alert(JSON.stringify(values)); // [3,5,8] >let apples = 3; let oranges = 5; // | s[0] | v[0] |s[1]| v[1] |s[2] | v[2] |s[3] let str = f`Sum of $ + $ =\n $!`;

В примере выше видно, что строка разбивается по очереди на части: «кусок строки» – «параметр» – «кусок строки» – «параметр».

  • Участки строки идут в первый аргумент-массив strings .
  • У этого массива есть дополнительное свойство strings.raw . В нём находятся строки в точности как в оригинале. Это влияет на спец-символы, например в strings символ \n – это перевод строки, а в strings.raw – это именно два символа \n .
  • Дальнейший список аргументов функции шаблонизации – это значения выражений в $ , в данном случае их три.

Зачем strings.raw ?

В отличие от strings , в strings.raw содержатся участки строки в «изначально введённом» виде.

То есть, если в строке находится \n или \u1234 или другое особое сочетание символов, то оно таким и останется.

Это нужно в тех случаях, когда функция шаблонизации хочет произвести обработку полностью самостоятельно (свои спец. символы?). Или же когда обработка спец. символов не нужна – например, строка содержит «обычный текст», набранный непрограммистом без учёта спец. символов.

Как видно, функция имеет доступ ко всему: к выражениям, к участкам текста и даже, через strings.raw – к оригинально введённому тексту без учёта стандартных спец. символов.

Функция шаблонизации может как-то преобразовать строку и вернуть новый результат.

В простейшем случае можно просто «склеить» полученные фрагменты в строку:

'use strict'; // str восстанавливает строку function str(strings, . values) < let str = ""; for(let i=0; i// последний кусок строки str += strings[strings.length-1]; return str; > let apples = 3; let oranges = 5; // Sum of 3 + 5 = 8! alert( str`Sum of $ + $ = $!`);

Функция str в примере выше делает то же самое, что обычные обратные кавычки. Но, конечно, можно пойти намного дальше. Например, генерировать из HTML-строки DOM-узлы (функции шаблонизации не обязательно возвращать именно строку).

Или можно реализовать интернационализацию. В примере ниже функция i18n осуществляет перевод строки.

Она подбирает по строке вида «Hello, $!» шаблон перевода «Привет, !» (где – место для вставки параметра) и возвращает переведённый результат со вставленным именем name :

'use strict'; let messages = < "Hello, !": "Привет, !" >; function i18n(strings, . values) < // По форме строки получим шаблон для поиска в messages // На месте каждого из значений будет его номер: , , … let pattern = ""; for(let i=0; i'; > pattern += strings[strings.length-1]; // Теперь pattern = "Hello, !" let translated = messages[pattern]; // "Привет, !" // Заменит в "Привет, " цифры вида на values[num] return translated.replace(/\/g, (s, num) => values[num]); > // Пример использования let name = "Вася"; // Перевести строку alert( i18n`Hello, $!` ); // Привет, Вася!

Итоговое использование выглядит довольно красиво, не правда ли?

Разумеется, эту функцию можно улучшить и расширить. Функция шаблонизации – это своего рода «стандартный синтаксический сахар» для упрощения форматирования и парсинга строк.

Улучшена поддержка Юникода

Внутренняя кодировка строк в JavaScript – это UTF-16, то есть под каждый символ отводится ровно два байта.

Но под всевозможные символы всех языков мира 2 байт не хватает. Поэтому бывает так, что одному символу языка соответствует два Юникодных символа (итого 4 байта). Такое сочетание называют «суррогатной парой».

Самый частый пример суррогатной пары, который можно встретить в литературе – это китайские иероглифы.

Заметим, однако, что не всякий китайский иероглиф – суррогатная пара. Существенная часть «основного» Юникод-диапазона как раз отдана под китайский язык, поэтому некоторые иероглифы – которые в неё «влезли» – представляются одним Юникод-символом, а те, которые не поместились (реже используемые) – двумя.

alert( '我'.length ); // 1 alert( '��'.length ); // 2

В тексте выше для первого иероглифа есть отдельный Юникод-символ, и поэтому длина строки 1 , а для второго используется суррогатная пара. Соответственно, длина – 2 .

Китайскими иероглифами суррогатные пары, естественно, не ограничиваются.

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

alert( '��'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X alert( '��'.length ); // 2, FACE WITH TEARS OF JOY

В современный JavaScript добавлены методы String.fromCodePoint и str.codePointAt – аналоги String.fromCharCode и str.charCodeAt , корректно работающие с суррогатными парами.

Например, charCodeAt считает суррогатную пару двумя разными символами и возвращает код каждой:

// как будто в строке два разных символа (на самом деле один) alert( '��'.charCodeAt(0) + ' ' + '��'.charCodeAt(1) ); // 55349 56499

…В то время как codePointAt возвращает его Unicode-код суррогатной пары правильно:

// один символ с "длинным" (более 2 байт) unicode-кодом alert( '��'.codePointAt(0) ); // 119987

Метод String.fromCodePoint(code) корректно создаёт строку из «длинного кода», в отличие от старого String.fromCharCode(code) .

// Правильно alert( String.fromCodePoint(119987) ); // �� // Неверно! alert( String.fromCharCode(119987) ); // 풳

Более старый метод fromCharCode в последней строке дал неверный результат, так как он берёт только первые два байта от числа 119987 и создаёт символ из них, а остальные отбрасывает.

\u

Есть и ещё синтаксическое улучшение для больших Unicode-кодов.

В JavaScript-строках давно можно вставлять символы по Unicode-коду, вот так:

alert( "\u2033" ); // ″, символ двойного штриха

Синтаксис: \uNNNN , где NNNN – четырёхзначный шестнадцатиричный код, причём он должен быть ровно четырёхзначным.

«Лишние» цифры уже не войдут в код, например:

alert( "\u20331" ); // Два символа: символ двойного штриха ″, а затем 1

Чтобы вводить более длинные коды символов, добавили запись \u , где NNNNNNNN – максимально восьмизначный (но можно и меньше цифр) код.

alert( "\u" ); // ��, китайский иероглиф с этим кодом

Unicode-нормализация

Во многих языках есть символы, которые получаются как сочетание основного символа и какого-то значка над ним или под ним.

Например, на основе обычного символа a существуют символы: àáâäãåā . Самые часто встречающиеся подобные сочетания имеют отдельный Юникодный код. Но отнюдь не все.

Для генерации произвольных сочетаний используются несколько Юникодных символов: основа и один или несколько значков.

Например, если после символа S идёт символ «точка сверху» (код \u0307 ), то показано это будет как «S с точкой сверху» Ṡ .

Если нужен ещё значок над той же буквой (или под ней) – без проблем. Просто добавляем соответствующий символ.

К примеру, если добавить символ «точка снизу» (код \u0323 ), то будет «S с двумя точками сверху и снизу» Ṩ .

Пример этого символа в JavaScript-строке:

alert("S\u0307\u0323"); // Ṩ

Такая возможность добавить произвольной букве нужные значки, с одной стороны, необходима, а с другой стороны – возникает проблемка: можно представить одинаковый с точки зрения визуального отображения и интерпретации символ – разными сочетаниями Unicode-кодов.

alert("S\u0307\u0323"); // Ṩ alert("S\u0323\u0307"); // Ṩ alert( "S\u0307\u0323" == "S\u0323\u0307" ); // false

В первой строке после основы S идёт сначала значок «верхняя точка», а потом – нижняя, во второй – наоборот. По кодам строки не равны друг другу. Но символ задают один и тот же.

С целью разрешить эту ситуацию, существует Юникодная нормализация, при которой строки приводятся к единому, «нормальному», виду.

В современном JavaScript это делает метод str.normalize().

alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true

Забавно, что в данной конкретной ситуации normalize() приведёт последовательность из трёх символов к одному: \u1e68 (S с двумя точками).

alert( "S\u0307\u0323".normalize().length ); // 1, нормализовало в один символ alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true

Это, конечно, не всегда так, просто в данном случае оказалось, что именно такой символ в Юникоде уже есть. Если добавить значков, то нормализация уже даст несколько символов.

Для большинства практических задач информации, данной выше, должно быть вполне достаточно, но если хочется более подробно ознакомиться с вариантами и правилами нормализации – они описаны в приложении к стандарту Юникод Unicode Normalization Forms.

Полезные методы

Добавлен ряд полезных методов общего назначения:

  • str.includes(s) – проверяет, включает ли одна строка в себя другую, возвращает true/false .
  • str.endsWith(s) – возвращает true , если строка str заканчивается подстрокой s .
  • str.startsWith(s) – возвращает true , если строка str начинается со строки s .
  • str.repeat(times) – повторяет строку str times раз.

Конечно, всё это можно было сделать при помощи других встроенных методов, но новые методы более удобны.

Итого

  • Строки-шаблоны – для удобного задания строк (многострочных, с переменными), плюс возможность использовать функцию шаблонизации для самостоятельного форматирования.
  • Юникод – улучшена работа с суррогатными парами.
  • Полезные методы для проверок вхождения одной строки в другую.

Как можно динамически создать функцию с кодом из произвольной строки js

Есть функция, которая записана в строку

var fstr = "function (arg)";

Следующий код не работает

var fstr = "function (arg)"; eval(fstr);

и это ооочень печально
Умею распарсить аргументы и тело функции
Путь названия аргументов хранятся в массиве aargs, а тело функции в fbodystr

var aargs=["'arg'"]; var fbodystr = "return 'hello'+\"world\"+arg";

Функцию ешё можно создать с помощью new Function(аргументы, тело)
Пробую

var fref = eval("new Function("+aargs.toString()+", '"+fbodystr +"')")

ИМХО не работает, так как кавычек не хватает.. При определении new Fun.. используются «‘» и в теле функции они тоже есть!
Как быть, как динамически из строки создать функцию, поскажите..

С уважением, Иван

Re: [JS] создание функции на лету из строки

От: WSN
Дата: 26.11.07 12:33
Оценка:

Здравствуйте, WSN, Вы писали:

WSN>Как быть, как динамически из строки создать функцию, поскажите..

Сделал через БООЛЬШУЮ Ж.. но работает.

var args=["aa", "bb"]; var fbody = "alert(aa+bb)"; var fnref = function(args, body) < return function() < for (var i = 0; i>(args, fbody) fnref("hello ", "world");

Вообщем вот.. Жду каких нить более трезвых решений, потому что тело такой созданной функции по ссылке потом получить будет невозможно..
Задача в пределах сереализации объектов jscript через xml
И все это надо проделать для того, чтобы серелиазовать и воосстановить функцию.. Так что если каки-нить мысли по сереалиции появятся, пишите буду рад

С уважением, Иван

Re: [JS] создание функции на лету из строки

От: anonymous http://denis.ibaev.name/
Дата: 26.11.07 12:44
Оценка:

Здравствуйте, WSN, Вы писали:

WSN>Есть функция, которая записана в строку
WSN>

WSN>var fstr = "function (arg)"; WSN>

WSN>Следующий код не работает
WSN>

WSN>var fstr = "function (arg)"; WSN>eval(fstr); WSN>
var str = "function(a) < alert(a); >"; var func = eval(str); func(1);

Re[2]: [JS] создание функции на лету из строки

От: WSN
Дата: 26.11.07 13:09
Оценка:

Здравствуйте, anonymous, Вы писали:

A>

A>var str = "function(a) < alert(a); >"; A>var func = eval(str); A>func(1); A>

Да супер! Если бы это еще работало. У меня IE6. В нем такое НЕ выполняется!
Мне тоже это очень странно стало!
Может это баг.. но даже если это баг, надо как-то обойти его..

Прошу дельных предложений.
С уважением, Иван

Re: [JS] создание функции на лету из строки

От: .
Дата: 26.11.07 13:41
Оценка: 2 (1)

WSN wrote:

> Следующий код не работает
>
> var fstr = «function (arg)»;
> eval(fstr);

У меня такое заработало:

var fstr = "function (arg)"; eval("(function())()")(1);

Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: [JS] создание функции на лету из строки

От: WSN
Дата: 26.11.07 14:04
Оценка:

Здравствуйте, ., Вы писали:
.>У меня такое заработало:
.>

.>var fstr = "function (arg)"; .>eval("(function())()")(1); .>

У меня тоже! Спасибо!
Но все же.. почему не проходит прямое создание.

Re[2]: [JS] создание функции на лету из строки

От: SuhanovSergey
Дата: 26.11.07 14:08
Оценка:

Здравствуйте, ., Вы писали:

.>WSN wrote:

>> Следующий код не работает
>>
>> var fstr = «function (arg)»;
>> eval(fstr);
.>
.>У меня такое заработало:
.>

.>var fstr = "function (arg)"; .>eval("(function())()")(1); .>

Ещё вариант. По сути тоже, что предлагал ., но имхо попроще для чтения.

var fstr = "function (arg)"; eval("var tmp="+fstr+"; tmp;")(1);

Re[3]: [JS] создание функции на лету из строки

От: SuhanovSergey
Дата: 26.11.07 15:09
Оценка: 3 (1) +1

Здравствуйте, WSN, Вы писали:

WSN>Здравствуйте, ., Вы писали:
.>>У меня такое заработало:
.>>

.>>var fstr = "function (arg)"; .>>eval("(function())()")(1); .>>

WSN>У меня тоже! Спасибо!
WSN>Но все же.. почему не проходит прямое создание.
eval(«function(a) < alert(a); >«)(1) не работает в IE, Opera, Safari. Рабоатет в FF. Интересно, кто прав?

Похоже FF не прав. Смотрим определение eval:

eval (x) When the eval function is called with one argument x, the following steps are taken: 1. If x is not a string value, return x. 2. Parse x as a Program. If the parse fails, throw a SyntaxError exception (but see also clause 16). 3. Evaluate the program from step 2. 4. . 

Икак, параметр должен соответствовать грамматике Program. Смотрим грамматику:

Program : SourceElements SourceElements : SourceElement SourceElements SourceElement SourceElement : Statement Statement : Block VariableStatement EmptyStatement ExpressionStatement IfStatement IterationStatement ContinueStatement BreakStatement ReturnStatement WithStatement LabelledStatement SwitchStatement ThrowStatement TryStatement ExpressionStatement : [lookahead ∉ ] Expression ;

Получается, что ExpressionStatement не может начинаться со слова function, о чём кстати пишется далее в комментариях

Note that an ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.

Получается, что голый ExpressionStatement нельзя писать в eval, но можно, например, operator,:
var fstr = «function(a) < alert(a); >«;
eval(«0, «+fstr)(1);

Re[4]: [JS] создание функции на лету из строки

От: AKS.
Дата: 27.11.07 04:30
Оценка:
 var args = 'a, b'; var fbodystr = 'alert("hello, " + a + " " + b + "!")'; var F = new Function(args, fbodystr);// создание функции посредством конструктора F('my', 'world'); var fstr = "function S(a) < alert(a); >";// создание именованной функции eval(fstr) S(1);// вызов по имени

Re[4]: [JS] создание функции на лету из строки

От: Аноним
Дата: 03.12.07 18:47
Оценка:

Здравствуйте, SuhanovSergey, Вы писали:
SS>Получается, что голый ExpressionStatement нельзя писать в eval, но можно, например, operator,:

В eval можно писать всё, что можно писать в global scope, т.е. всё, кроме return, break, continue.

Разница между FunctionExpression и FunctionDeclaration в том, что первое возвращает ссылку на функцию, а второе undefined. Именно поэтому в eval надо писать «голый ExpressionStatement», частным случаем которого является FunctionExpression, но «нельзя» FunctionDeclaration.

Re[5]: [JS] создание функции на лету из строки

От: AKS.
Дата: 04.12.07 08:22
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, SuhanovSergey, Вы писали:

А>Именно поэтому в eval надо писать «голый ExpressionStatement», частным случаем которого является FunctionExpression, но «нельзя» FunctionDeclaration.

Что значит «нельзя»? В предыдущем сообщении я привел пример, свидетельствующий об обратном.

Re[6]: [JS] создание функции на лету из строки

От: Аноним
Дата: 04.12.07 10:24
Оценка:

Здравствуйте, AKS., Вы писали:

AKS>Что значит «нельзя»? В предыдущем сообщении я привел пример, свидетельствующий об обратном.

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

Re[7]: [JS] создание функции на лету из строки

От: AKS.
Дата: 04.12.07 14:14
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Там пример создания глобальной функции — eval при этом возвращает void, а не ссылку на функцию.

Я не писал о том, что возвращает eval. Я заметил, что Вы не правы, утверждая: «в eval . писать . «нельзя» FunctionDeclaration».

Re[8]: [JS] создание функции на лету из строки

От: Аноним
Дата: 04.12.07 15:09
Оценка:

Здравствуйте, AKS., Вы писали:

AKS>Я не писал о том, что возвращает eval.

Тогда на кой было встревать в тред про значение, возвращаемое из eval?

AKS> Я заметил, что Вы не правы, утверждая: «в eval . писать . «нельзя» FunctionDeclaration».

Еще немного, и Вам удастся разглядеть контекст, в котором это утверждалось.

Re[9]: [JS] создание функции на лету из строки

От: AKS.
Дата: 05.12.07 05:34
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Тогда на кой было встревать в тред про значение, возвращаемое из eval?

Во-первых, разве интелегентные люди так общаются? Я имею ввиду «на кой» и «встревать».
А во-вторых, здесь нет треда, называющегося «Про значение, возвращаемое из eval»!

А>Еще немного, и Вам удастся разглядеть контекст, в котором это утверждалось.

Так ведь контекст-то один — контекст спецификации ECMAScript Language. Тем не менее, я готов узнать о вашей интерпретации, а именно, каким образом в eval надо писать:

А>. «голый ExpressionStatement», частным случаем которого является FunctionExpression
, чтобы при этом случилось то, что Вы называете:

А>. возвращает ссылку на функцию

Re: [JS] создание функции на лету из строки

От: _JoKe_
Дата: 06.12.07 10:10
Оценка:

WSN>Есть функция, которая записана в строку
WSN>

WSN>var fstr = "function (arg)"; WSN>

WSN>Следующий код не работает
WSN>

WSN>var fstr = "function (arg)"; WSN>eval(fstr); WSN>

WSN>и это ооочень печально

eval("var fstr = function (arg)"); alert( fstr("!") );

Eval в программировании

Программный код может быть написан на различных языках разработки. Каждый из них поддерживает свой собственный список операторов, команд и инструментов. Некоторые «опции» у ЯП схожи между собой. Примеры – циклы и функция Eval.

В статье речь пойдет именно о ней. Предстоит выяснить, для чего она необходима в коде, за выполнение чего отвечает, как грамотно использовать соответствующий компонент. Далее будут приведены примеры на наиболее известных и распространенных языках программирования: PHP, JavaScript, Python.

Определение функции

Перед тем как рассматривать применение в коде eval, необходимо разобраться с одним понятием. Каждый разработчик должен понимать, что такое функция (function).

Так называется подпрограмма. Это фрагмент исходного программного кода, к которому можно обратиться из другого места приложения. Обычно с функцией связывается идентификатор. Многие языки разработки поддерживают безымянные functions.

Функции могут принимать параметры. Они возвращают некоторые значения, включая пустые. В этом случае соответствующие операции называются процедурами. Такие команды могут иметь различный синтаксис, включая ключевые слова.

Необходимо обратить внимание на то, что каждая функция должна для нормальной работы:

  • быть определена конкретным образом;
  • быть объявлена в исходном приложении.

При объявлении используется имя со списком имен и типов передаваемых аргументов, тип возвращаемого значения. Определение – это непосредственный код, который реализовывает заданная «команда».

Eval – это…

Теперь можно разобраться с тем, что собой представляет функция типа Eval. Она во всех языках разработки используется для одного и того же спектра действий. В коде eval применяется для того, чтобы считать строку.

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

В Python

Далее предстоит рассмотреть упомянутую function на различных языках программирования. Рекомендуется начать с наиболее распространенного – Python. Он используется для создания различных приложений как новичками, так и более опытными разработчиками.

Функция eval в Python будет выполнять строку-выражение, которая передается в виде обязательного аргумента. Возвращает результат реализации соответствующей строчки.

В качестве аргументов в eval передается строка-выражение expression. Она обязательна для исполнения. В качестве необязательных компонентов могут быть переданы значения глобальные (globals) и локальные (locals). Глобальные переменные обязательно являются словарем dict, а локальные могут выступать в качестве любого отображающего объекта.

Форма представления eval в коде:

  • expression – строка-выражение, которое необходимо исполнить или объект, возвращающий compile();
  • globals=None – словарь глобального пространства, в котором исполняется выражение;
  • locals=None – переменные локальной области.

При реализации динамического кода, записанного непосредственно в строку, рекомендуется обратиться к команде exec().

Пример с пользовательским вводом

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

Основная сила evil заключается в том, что она позволяет динамически выполнять операторы. С ее помощью удается реализовывать произвольные объекты кода.

Выше – фрагмент, предлагающий пользователю ввести функцию для дальнейшей обработки. При его исполнении будет следующий результат:

Без eval function не получится исполнять команды, которые будут введены клиентом.

В PHP

Еще одним языком, в котором встречается рассматриваемая подпрограмма – это PHP. Здесь она позволяет реализовать код, написанный в строке. Используется в крайних случаях – когда разработчики уверены, что для воспроизведения отсутствует необходимый функционал. Особое внимание придется уделить исключениям обработки таким методом данных, которые вводятся пользователем.

Форма представления программного кода с eval:

Здесь стоит запомнить следующее:

  1. Code – это выполняемая строка в PHP. Она не должна быть обернута открывающимися и закрывающимися тегами.
  2. Предусматривается переключение между режимами PHP и HTML.
  3. Если указать ключевое слово return, система прекратит исполнение заданной команды в строчке.

Функции eval возвращают null, если не вызывается return. В противном случае происходит возврат значения, переданного return. Начиная с PHP 7, при наличии ошибки в исходной команде, система вызывает исключение ParseError. В этой ситуации возвращается false, после чего начинается нормальное функционирование последующих фрагментов приложения.

Наглядный пример

А вот – пример простого слияния текста в PHP:

После реализации этого фрагмента на экране появится следующая картина:

При обнаружении фатальной ошибки в eval будет прекращена работа всего скрипта на PHP.

Работа в JavaScript

В коде на JavaScript eval является встроенной командой. Она дает возможность реализовать строку кода и имеет следующую форму представления:

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

При строгом режиме eval поддерживает собственное лексическое окружение. В разработке соответствующая команда встречается редко.

Выше – наглядный пример реализации программного кода на JavaScript.

Хотите освоить современную IT-специальность? Огромный выбор курсов по востребованным IT-направлениям есть в Otus !

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *