\"\n>\n```\n\n## Когда eval всё ещё встречается\n\n```javascript\n// 1. Старый код (jQuery era)\n// 2. Некоторые шаблонизаторы (template literals лучше)\n// 3. Некоторые библиотеки (обычно можно найти замену)\n// 4. Инструменты отладки (browser DevTools используют eval)\n```\n\n## Правило thumb\n\n```javascript\n// НИКОГДА не используй eval, если:\n// ✓ Есть альтернатива\n// ✓ Нужна безопасность\n// ✓ Нужна производительность\n// ✓ Нужна отладка\n// ✓ Нужна читаемость\n\n// Используй eval ТОЛЬКО если:\n// - Ты в изолированном контексте (Worker, iframe)\n// - Ты 100% контролируешь код\n// - Нет другого выхода\n// - Ты знаешь что делаешь\n```\n\n## Практический пример (неправильно vs правильно)\n\n```javascript\n// НЕПРАВИЛЬНО - опасная система шаблонов\nfunction renderTemplate(template, data) {\n // Заменяем {{x}} на значение x\n const code = template.replace(/{{(\\w+)}}/g, (match, key) => {\n return `'${data[key]}'`;\n });\n return eval('`' + code + '`');\n}\n\nrenderTemplate('Hello {{name}}', { name: 'John' }); // OK\nrenderTemplate('Hello {{name}}; console.log(\"hacked\") }}', {}); // Опасно!\n\n// ПРАВИЛЬНО - безопасная система шаблонов\nfunction renderTemplate(template, data) {\n return template.replace(/{{(\\w+)}}/g, (match, key) => {\n return data[key] || '';\n });\n}\n\nrenderTemplate('Hello {{name}}', { name: 'John' }); // OK\nrenderTemplate('Hello {{name}}; console.log(\"safe\") }}', {}); // Безопасно!\n```\n\n## Итого\n\nevalв JavaScript:\n1. **Выполняет строку как код** в текущем контексте\n2. **Имеет доступ к локальным переменным**\n3. **Очень медленно** - код интерпретируется при каждом вызове\n4. **Опасен для безопасности** - может выполнить вредоносный код\n5. **Затрудняет отладку** - код невидим в стек-трейсах\n6. **Ломает статический анализ** - IDE не может помочь\n7. **НИКОГДА не используй** без очень хорошей причины\n\nПрактический совет: если ты думаешь использовать eval, сначала подумай\n3 раза. Потом подумай еще раз. Потом используй альтернативу.","dateCreated":"2026-04-03T17:55:03.519534","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как работает eval?

2.0 Middle🔥 162 комментариев
#JavaScript Core

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает eval в JavaScript

Это важный вопрос, потому что 90% разработчиков говорят "никогда не используй eval!", но не все понимают почему. Давайте разберемся.

Что такое eval?

eval - это встроенная функция, которая выполняет JavaScript код из строки:

// Базовое использование
const result = eval('2 + 2'); // 4
console.log(result); // 4

// Выполнение кода
eval('console.log("Hello from eval")'); // Hello from eval

// Создание переменных
eval('var x = 5');
console.log(x); // 5

// Выполнение функций
eval('function greet(name) { return "Hello " + name; }');
console.log(greet('John')); // Hello John

Как eval работает "под капотом"?

// eval выполняет код в текущем контексте (scope)
var globalVar = 'global';

function example() {
  var localVar = 'local';
  
  eval('console.log(globalVar)'); // global - доступна
  eval('console.log(localVar)'); // local - доступна!
  eval('var evalVar = "eval"; console.log(evalVar)'); // eval
}

example();

// Это ключевая фишка eval - он имеет доступ к локальным переменным!
// Обычные функции этого не могут:

function normalFunction() {
  var localVar = 'local';
  
  function inner() {
    console.log(localVar); // local - работает через closure
  }
  inner();
}

Различные типы eval

Прямой eval (Direct eval)

// Имеет доступ к локальной области видимости
var x = 1;
function test1() {
  var x = 2;
  eval('console.log(x)'); // 2 - использует локальный x!
}
test1();

Непрямой eval (Indirect eval)

// Выполняется в глобальном контексте
var x = 1;
function test2() {
  var x = 2;
  (0, eval)('console.log(x)'); // 1 - использует глобальный x!
  // или
  const evalFn = eval;
  evalFn('console.log(x)'); // 1
}
test2();

// Трюк с (0, eval) часто используется в библиотеках

Почему eval опасен?

Опасность 1: Проблемы безопасности (XSS)

// Пользователь вводит код
const userInput = 'console.log("hack"); fetch("/steal-data")';

// Разработчик делает так (НИКОГДА!):
eval(userInput); // Выполнит вредоносный код!

// Правильно:
const parsed = JSON.parse(userInput);
// или используй более безопасные парсеры

Опасность 2: Производительность

// eval требует интерпретации строки при КАЖДОМ вызове
for (let i = 0; i < 1000000; i++) {
  eval('1 + 1'); // Очень медленно!
}

// Правильно:
for (let i = 0; i < 1000000; i++) {
  1 + 1; // Быстро, код оптимизируется
}

Опасность 3: Отладка

// eval код не видно в стек-трейсе
eval(`
  function buggyFunction() {
    throw new Error('Bug');
  }
  buggyFunction();
`);
// Stack trace будет бесполезен

// К тому же трудно дебажить код, загруженный из строки

Опасность 4: Статический анализ

// Инструменты не могут анализировать код в eval
eval('const x = 5'); // Лinter не знает про x
console.log(x); // Лinter не знает что это существует

// IDE не может помочь с автодополнением

Опасность 5: Непредсказуемость

var y = 'global';

function confusing() {
  var y = 'local';
  
  const code = 'y'; // какой y вернет eval?
  
  const result = eval(code); // 'local' или 'global'?
  console.log(result); // 'local' (прямой eval)
}

confusing();

// Непредсказуемо и запутанно!

Реальные примеры использования eval (когда это оправдано)

Редко оправданное использование 1: JSON.parse

// СТАРЫЙ способ (eval) - НИКОГДА!
const data = eval('(' + jsonString + ')');

// ПРАВИЛЬНЫЙ способ (всегда):
const data = JSON.parse(jsonString);

// JSON.parse безопаснее и быстрее

Редко оправданное использование 2: Динамические вычисления

// Калькулятор, который парсит математические выражения
// ОЧЕНЬ ПЛОХО:
function calculate(expression) {
  return eval(expression); // Опасно!
}
calculate('2 + 2'); // 4
calculate('Math.max(5, 3)'); // 5

// ХОРОШО: используй парсер выражений
import { evaluate } from 'mathjs';
function calculate(expression) {
  return evaluate(expression);
}

// или строго контролируй:
function safeCalculate(expression) {
  // Проверяй, что это только числа и операторы
  if (!/^[0-9+\-*/().,\s]*$/.test(expression)) {
    throw new Error('Invalid expression');
  }
  return eval(expression);
}

Редко оправданное использование 3: Динамические плагины

// Система плагинов, которая загружает код
// ОЧЕНЬ опасно, но если ДОЛЖНО быть:

// 1. Загрузи в Web Worker (изолированный контекст)
// 2. Используй iframe с sandbox
// 3. Используй V8 (Node.js) с изолированным контекстом

// НО НИКОГДА не eval код от пользователей прямо!

// Или используй более безопасные альтернативы:
import JEXL from 'jexl'; // Безопасный парсер выражений
const context = { x: 5, y: 3 };
await JEXL.eval('x + y', context); // 8

Альтернативы eval

Альтернатива 1: Function constructor

// Немного безопаснее, но всё ещё плохо
const fn = new Function('a', 'b', 'return a + b');
fn(2, 3); // 5

// Но:
// - Работает только в глобальном scope
// - Медленно
// - Трудно отлаживать

Альтернатива 2: Парсеры выражений

// Для простых выражений
import { evaluate } from 'mathjs';
evaluate('2 + 3 * 4'); // 14

// Для более сложных
import JEXL from 'jexl';
await JEXL.eval('x > 5 && y < 10', { x: 6, y: 8 }); // true

Альтернатива 3: JSON

// Если нужно передать данные, используй JSON
const jsonString = '{"x": 5, "y": 3}';
const data = JSON.parse(jsonString); // Безопасно!

Альтернатива 4: Web Workers

// Для выполнения непроверенного кода в изолированном контексте
const worker = new Worker('worker.js');
worker.postMessage({ code: userCode });
worker.onmessage = (e) => {
  console.log(e.data);
};

// В worker.js:
self.onmessage = (e) => {
  try {
    const result = eval(e.data.code); // eval в Worker - безопаснее
    self.postMessage(result);
  } catch (error) {
    self.postMessage({ error: error.message });
  }
};

Альтернатива 5: iframe с sandbox

<!-- Самая безопасная изоляция -->
<iframe 
  sandbox="sandbox"
  srcdoc="<script>/* пользовательский код */</script>"
></iframe>

Когда eval всё ещё встречается

// 1. Старый код (jQuery era)
// 2. Некоторые шаблонизаторы (template literals лучше)
// 3. Некоторые библиотеки (обычно можно найти замену)
// 4. Инструменты отладки (browser DevTools используют eval)

Правило thumb

// НИКОГДА не используй eval, если:
// ✓ Есть альтернатива
// ✓ Нужна безопасность
// ✓ Нужна производительность
// ✓ Нужна отладка
// ✓ Нужна читаемость

// Используй eval ТОЛЬКО если:
// - Ты в изолированном контексте (Worker, iframe)
// - Ты 100% контролируешь код
// - Нет другого выхода
// - Ты знаешь что делаешь

Практический пример (неправильно vs правильно)

// НЕПРАВИЛЬНО - опасная система шаблонов
function renderTemplate(template, data) {
  // Заменяем {{x}} на значение x
  const code = template.replace(/{{(\w+)}}/g, (match, key) => {
    return `'${data[key]}'`;
  });
  return eval('`' + code + '`');
}

renderTemplate('Hello {{name}}', { name: 'John' }); // OK
renderTemplate('Hello {{name}}; console.log("hacked") }}', {}); // Опасно!

// ПРАВИЛЬНО - безопасная система шаблонов
function renderTemplate(template, data) {
  return template.replace(/{{(\w+)}}/g, (match, key) => {
    return data[key] || '';
  });
}

renderTemplate('Hello {{name}}', { name: 'John' }); // OK
renderTemplate('Hello {{name}}; console.log("safe") }}', {}); // Безопасно!

Итого

evalв JavaScript:

  1. Выполняет строку как код в текущем контексте
  2. Имеет доступ к локальным переменным
  3. Очень медленно - код интерпретируется при каждом вызове
  4. Опасен для безопасности - может выполнить вредоносный код
  5. Затрудняет отладку - код невидим в стек-трейсах
  6. Ломает статический анализ - IDE не может помочь
  7. НИКОГДА не используй без очень хорошей причины

Практический совет: если ты думаешь использовать eval, сначала подумай 3 раза. Потом подумай еще раз. Потом используй альтернативу.