Вбудована функція eval дозволяє виконувати рядок, як код.
Синтаксис:
let result = eval(code);Наприклад:
let code = 'alert("Привіт")';
eval(code); // ПривітРядок коду може бути великий, містити перехід на інший рядок, оголошення функцій, змінні тощо.
Результатом eval буде результат виконання останньої інструкції.
Наприклад:
let value = eval('1+1');
alert(value); // 2let 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 x = 1;
{
  let x = 5;
  window.eval('alert(x)'); // 1 (глобальна змінна)
}Якщо коду всередині eval потрібні локальні змінні, поміняйте eval на new Function та передавайте необхідні дані як аргументи:
let f = new Function('a', 'alert(a)');
f(5); // 5Конструкція new Function пояснюється у розділі Синтаксис "new Function". Вона створює функцію рядка в глобальній області видимості. Отже, локальні змінні для неї невидимі, але завжди можна передати їх як аргументи. Виходить дуже акуратний код, як у прикладі вище.
Підсумки
Виклик eval(code) виконує рядок коду та повертає результат останньої інструкції.
- Це рідко використовується в сучасному JavaScript, тому що в цьому нема потреби.
- Можливий доступ до зовнішніх локальних змінних. Це вважається поганою практикою.
- Щоб виконати рядок коду за допомогою evalу глобальній області видимості, використовуйтеwindow.eval(code).
- Або ж, якщо ваш код потребує якихось даних із зовнішньої області видимості, то використовуйте new Function, передавши ці дані як аргументи.
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)