--- title: eval() slug: Web/JavaScript/Reference/Global_Objects/eval tags: - JavaScript - NeedsUpdate - Reference translation_of: Web/JavaScript/Reference/Global_Objects/eval ---
{{jsSidebar("Objects")}}

Warning: Выполнение кода JavaScript с текстовой строки - это невероятный риск для безопасности. Злоумышленнику слишком легко запустить какой угодно код, когда вы используете eval(). Смотрите  Никогда не используйте eval()!, ниже.

Метод eval() выполняет JavaScript код, представленный строкой.

{{EmbedInteractiveExample("pages/js/globalprops-eval.html")}}

Синтаксис

eval(string)

Параметры

string
Строка, представленная JavaScript выражением, оператором или последовательностью операторов. Выражение может содержать переменные и свойства существующих объектов.

Возвращаемое значение

Возвращает значение выполнения кода, переданного в функцию в виде строки. Если код не возвращает ничего - будет возвращено значение {{jsxref("undefined")}}.

Описание

eval() - функция глобального объекта.

Аргумент функции eval() - строка. eval() исполняет содержащееся в строке выражение, один или несколько операторов  JavaScript. Не стоит вызывать eval() для определения значения арифметического выражения; JavaScript вычисляет их автоматически.

eval() можно использовать для вычисления значения арифметического выражения, записанного в строковом виде, на более поздней стадии исполнения. Предположим, существует переменная x. Можно отложить вычисление выражения, в котором содержится х, если присвоить переменной это выражение в виде строки (допустим, "3 * x + 2"), а затем вызвать eval() в более поздней точке кода.

Если аргумент, переданный eval(), не является строкой, eval() возвращает его неизменным. В следующем примере определён конструктор String, и eval() не вычисляет значение выражения, записанного в строковом виде, а возвращает объект типа String.

eval(new String("2 + 2")); // возвращает объект типа String, содержащий "2 + 2"
eval("2 + 2");             // возвращает 4

Это ограничение легко обойти при помощи toString().

var expression = new String("2 + 2");
eval(expression.toString());

Если вы используете eval косвенно, вызовом его через ссылку, а не просто eval, в ECMAScript 5 это работает в глобальной области видимости, а не в локальной; это значит, что eval будет вызван в глобальной области видимости, а код будет выполнен с отсутствием доступа к локальным переменным в пределах области видимости, где он был вызван.

function test() {
  var x = 2, y = 4;
  console.log(eval("x + y"));  // Прямой вызов, использует локальную области видимости, результат - 6
  var geval = eval;
  console.log(geval("x + y")); // Непрямой вызов, использует глобальную область видимости, бросит ReferenceError, т.к. `x` - не определён
}

Не используйте eval без необходимости!

eval() - опасная функция, которая выполняет код, проходящий со всеми привилегиями вызывателя. Если вы запускаете eval() со строкой, на которую могут влиять злоумышленники, то вы можете запустить вредоносный код на устройство пользователя с правами вашей веб-страницы/расширения. Наиболее важно, код третьей стороны может видеть область видимости, в которой был вызван eval(), что может может привести к атакам, похожим на {{jsxref("Global_Objects/Function", "Function")}}.

Также eval(),как правило, медленнее альтернатив, так как вызывает интерпретатор JS, тогда как многие другие конструкции оптимизированы современными JS движками.

Есть безопасные (и быстрые!) альтернативы eval() для общих случаев использования.

Доступ к свойствам

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

var obj = { a: 20, b: 30 };
var propname = getPropName();  // возвращает "a" или "b"

eval( "var result = obj." + propname );

Однако, eval() здесь не нужен. По факту, использование здесь его удивляет. Вместо него используйте доступ к свойствам, который быстрее и безопаснее:

var obj = { a: 20, b: 30 };
var propname = getPropName();  // возвращает "a" или "b"
var result = obj[ propname ];  //  obj[ "a" ] то же, что и obj.a

Используйте функции вместо исполнения фрагментов кода

У JavaScript функции первого класса, что значит, что вы можете передавать функции как аргументы, хранить их в переменных или свойствах объектов и так далее. Многие DOM API созданы с учётом этого, так что вы можете (и вам следует) писать:

// вместо setTimeout(" ... ", 1000) :
setTimeout(function() { ... }, 1000);

// вместо elt.setAttribute("onclick", "...") использовать:
elt.addEventListener("click", function() { ... } , false); 

Замыкания также полезны как способ создания функций с параметрами без конкатенации строк.

Разбор JSON (конвертирование строк в JavaScript объекты)

Если строка, переданная в eval(), содержит данные (к примеру, массив: "[1, 2, 3]"), а не код, вам следует рассмотреть JSON, позволяющий строке использовать подмножество JavaScript синтаксиса для представления данных. Смотрите также: Загрузка JSON и JavaScript в расширениях.

Заметьте, что синтаксис JSON ограничен в сравнении с JavaScript синтаксисом, многие валидные JavaScript литералы не распарсятся в JSON. К примеру, лишние запятые в конце выражений не разрешены в JSON, а имена свойств (ключи) в объектах должны быть в двойных кавычках. Будьте уверены использовать сериализацию JSON для создания строк, которые потом будут разбираться как JSON.

Передавайте данные вместо кода

К примеру, расширение, созданное изменять содержимое веб-страниц, должно иметь правила, определённые в XPath, а не JS коде.

Выполняйте код с ограниченными правами

Если выполнять код всё-таки необходимо, желательно это делать с уменьшенными привелегиями. Этот совет подходит, главным образом, к расширениям и XUL приложениям, которые могут использовать Components.utils.evalInSandbox.

Примеры

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

В следующем коде оба выражения содержат eval(), возвращающий 42. Первое определяется строкой "x + y + 1"; второе - строкой "42".

var x = 2;
var y = 39;
var z = "42";
eval("x + y + 1"); // возвращает 42
eval(z);           // вернёт 42

Использование eval для исполнения строки, содержащей операторы JavaScript

Следующий пример использует eval() для получения значения выражения str. Эта строка состоит из JavaScript выражений, печатающих в консоль, и, если x равен пяти, призывающих z значение 42, или 0 в противном случае. Когда второе выражение будет исполнено, eval() будет считать выражения выполненными, а также это установит значение выражению переменной z и вернёт его.

var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0; ";

console.log("z is ", eval(str));

Последнее выражение выполняется

eval() вернёт значение последнего выполняемого выражения

var str = "if ( a ) { 1+1; } else { 1+2; }";
var a = true;
var b = eval(str);  // вернёт 2

console.log("b is : " + b);

a = false;
b = eval(str);  // вернёт 3

console.log("b is : " + b);

eval как строковое определение функции, включающее "(" и ")" как префикс и суффикс

var fctStr1 = "function a() {}"
var fctStr2 = "(function a() {})"
var fct1 = eval(fctStr1)  // вернёт undefined
var fct2 = eval(fctStr2)  // вернёт функцию

Спецификации

Спецификация Статус Комментарий
ECMAScript 1st Edition. Стандарт Изначальное определение.
{{SpecName('ES5.1', '#sec-15.1.2.1', 'eval')}} {{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-eval-x', 'eval')}} {{Spec2('ES6')}}

Поддержка браузерами

{{Compat("javascript.builtins.eval")}}

Gecko-специфичные замечания

Смотрите также