JS Advanced

new Function

Понять, как new Function создаёт функции из строк, чем отличается от eval, и почему обычно избегается.

Продвинутый (Advanced)
Нужно знать:Функцииeval

Кратко

new Function(arg1, arg2, ..., body) создаёт функцию из строки. Отличие от eval: создаёт новую функцию с изолированным scope (не видит локальные переменные). Но всё ещё опасен при user input. Используется в: шаблонизаторах, клиентах API.


Подробно

Синтаксис: const sum = new Function('a', 'b', 'return a + b'); console.log(sum(1, 2)); // 3

Последний аргумент — тело функции: const greet = new Function('name', 'return Hello, ${name}!'); console.log(greet('Анна')); // 'Hello, Анна!'

Отличие от eval: // eval — выполняет в текущем scope const x = 10; eval('x + 5'); // 15 — видит x

// new Function — создаёт новый scope const fn = new Function('return x + 5'); // fn(); // ReferenceError: x is not defined

Почему существует:

  • Динамическое создание функций из строк
  • Шаблонизаторы (Handlebars, EJS)
  • Клиенты API (gRPC-web)

Почему обычно избегается:

  • Опасно (как eval)
  • Не оптимизируется движком
  • Линтер не видит ошибки
  • Трудно отлаживать

Ментальная модель

new Function — как конструктор функции из чертежа. Вы даёте ему список параметров и тело (как строку). Он строит функцию. Но unlike eval — функция строится в изолированном цеху (новый scope).


Примеры

**Самый простой:**

javascript
const multiply = new Function('a', 'b', 'return a * b');
console.log(multiply(3, 4)); // 12

// Эквивалент:
// function multiply(a, b) { return a * b; }

Простейшая функция из строки.

**Простой:**

javascript
// new Function vs eval
const localVar = 42;

// eval видит localVar
eval('console.log(localVar)'); // 42

// new Function НЕ видит localVar
try {
  const fn = new Function('console.log(localVar)');
  fn(); // ReferenceError
} catch (e) {
  console.log('Функция не видит внешние переменные');
}

new Function изолирует scope — не видит внешние переменные.

**Реальный пример:**

javascript
// Динамический шаблон
function createTemplate(template) {
  return new Function('data', `
    return `${template}`;
  `);
}

const userTemplate = createTemplate('Привет, ${data.name}!');
console.log(userTemplate({ name: 'Анна' })); // 'Привет, А́нна!'

// Важно: template безопасен только если не содержит user input!
// Если template = user input — это eval с теми же рисками.

Динамический шаблон: new Function для генерации функций.


Частые ошибки

**Неправильно:** Думать, что new Function безопаснее eval

**Почему:** new Function изолирует scope, но всё ещё выполняет произвольный код.

**Правильно:** new Function = eval + изолированный scope. Всё ещё опасен.

**Неправильно:** Использовать new Function для простых функций

**Почему:** Обычные function declaration/expression проще, безопаснее и быстрее.

**Правильно:** new Function только для динамического создания из строк.


Важно запомнить

  • new Function(args, body) — создаёт функцию из строки
  • Изолирует scope (не видит локальные переменные)
  • Всё ещё опасен (как eval)
  • Используется в шаблонизаторах
  • Предпочитайте обычные функции

Связь

Назад: Вы знаете eval (JV21). new Function — родственный механизм с изолированной областью видимости.

Вперёд: Следующий урок (JV23) — обёртки примитивов — как примитивы получают методы.

Материалы курса JS Advanced — PROlab Academy.