JS Advanced

Именованные функциональные выражения (NFE)

Понять разницу между function expression и named function expression, и зачем имя внутри функции полезно для рекурсии и stack traces.

Продвинутый (Advanced)

Кратко

Named function expression — это функция, которая имеет имя внутри себя. Это имя доступно только внутри функции. Полезно для рекурсии, отладки (stack traces) и самоссылки. Но в большинстве случаев достаточно обычных функций или arrow functions.


Подробно

Function expression vs Named function expression:

// Function expression (anonymous) const add = function(a, b) { return a + b; };

// Named function expression const add = function addInternal(a, b) { return a + b; };

Имя addInternal доступно ТОЛЬКО внутри функции: const add = function addInternal(a, b) { console.log(addInternal.name); // 'addInternal' return a + b; };

console.log(addInternal); // ReferenceError — имя не доступно снаружи

Зачем использовать NFE:

  • Рекурсия (без присваивания в переменную):

const factorial = function fact(n) { return n <= 1 ? 1 : n * fact(n - 1); };

  • Stack traces — имя функции видно в ошибке:

// Anonymous: TypeError: ... at <anonymous> // Named: TypeError: ... at addInternal

  • Самоссылка:

const obj = { method: function self() { console.log(self === obj.method); // true } };

Современные альтернативы:

  • Обычная function declaration: function add() {}
  • Arrow function: const add = () => {}
  • Обычное имя переменной: const add = function() {}

NFE редко нужен в modern коде. Но полезно знать при чтении legacy кода.


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

NFE — как функция с паспортом. Обычная анонимная функция — как человек без документов (неизвестно кто). NFE — функция с именем, которое она носит только для себя. Полезно, если нужно знать своё имя (рекурсия) или если полиция спросит (stack trace).


Примеры

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

javascript
// Anonymous function expression
const greet = function(name) {
  console.log(`Hello, ${name}`);
};

// Named function expression
const greet = function greetFn(name) {
  console.log(greetFn.name); // 'greetFn'
};

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

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

javascript
// Рекурсия через NFE
const factorial = function fact(n) {
  if (n <= 1) return 1;
  return n * fact(n - 1);
};

console.log(factorial(5)); // 120
// fact доступна только внутри функции

NFE позволяет рекурсию без переменной-обёртки.

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

javascript
// В object literals — self-reference
const calculator = {
  history: [],
  add: function add(a, b) {
    const result = a + b;
    this.history.push({ op: 'add', args: [a, b], result });
    return result;
  }
};

// В stack trace видно имя 'add', а не '<anonymous>'

NFE в объекте: имя функции помогает при отладке.


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

**Неправильно:** Путать имя функции с именем переменной

**Почему:** const add = function addInternal() {} — имя переменной 'add', имя функции 'addInternal'.

**Правильно:** Имя переменной и имя функции — разные вещи.

**Неправильно:** Думать, что NFE нужен в каждом проекте

**Почему:** В modern коде достаточно function declarations и arrow functions.

**Правильно:** NFE — legacy паттерн. Знай для чтения чужого кода.


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

  • Имя NFE доступно только внутри функции
  • Полезно для рекурсии, stack traces, self-reference
  • Имя переменной ≠ имя функции
  • В modern коде редко нужен

Связь

Назад: Вы знаете функции (J9, J10) и стрелочные функции (J10). NFE — это вариант синтаксиса функций.

Вперёд: Следующий урок (JV3) — как объекты преобразуются в примитивы в операциях.

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