Function Declaration и Function Expression

Function Declaration и Function Expression

Почему важно различать эти два способа

В JavaScript функцию можно создать через Function Declaration и Function Expression. Оба способа рабочие, но ведут себя по-разному в контексте hoisting и читаемости кода.

Ключевой момент: выбор формы влияет на порядок использования функции и стиль архитектуры.

Проверь себя: почему одну функцию можно вызвать до объявления, а другую нет?

Function Declaration

sayHello();

function sayHello() {
  console.log('Hello');
}

Function Declaration поднимается целиком (hoisting), поэтому вызов до строки объявления работает.

Смотри, что важно: это удобно, но не стоит злоупотреблять "вызовом до объявления", чтобы не ухудшать читаемость.

Function Expression

const sayHi = function () {
  console.log('Hi');
};

sayHi();

Здесь функция хранится в переменной. Поведение зависит от правил переменной (const/let).

// sayHi(); // ReferenceError, если вызов до инициализации
const sayHi = function () {};

Если использовать var, переменная будет поднята и инициализирована как undefined, поэтому ошибка будет другой:

sayHi(); // TypeError: sayHi is not a function
var sayHi = function () {};

Здесь часто путаются: hoisting у переменной и hoisting у declaration - не одно и то же.

Когда что выбирать

Function Declaration часто выбирают для:

  • базовых "главных" функций модуля;
  • случаев, где функция логически независима.

Function Expression удобен для:

  • передачи функции как значения;
  • локальных функций в определенном контексте;
  • построения композиции с переменными.

Проверь себя: почему expression чаще встречается в колбэках и конфигурациях?

Именованное выражение

const calculate = function computeSum(a, b) {
  return a + b;
};

Внешне доступно имя переменной calculate, а внутреннее имя computeSum полезно для отладки стека вызовов.

Мини-сценарий: обработка результатов

function normalize(value) {
  return Number(value);
}

const isPassed = function (score) {
  return score >= 70;
};

const score = normalize('72');
console.log(isPassed(score));

Здесь declaration используется как базовая утилита, expression - как локальное правило.

Частые ошибки новичков

  • Пытаться вызвать expression до инициализации.
  • Смешивать стили без понятной причины.
  • Использовать анонимные expression повсюду и терять читаемость.
  • Делать вывод "declaration всегда лучше" или наоборот.

Анти-провал: придерживайся консистентного стиля в модуле и учитывай поведение hoisting.

Что будет, если изменить входные данные

В примере со score, если normalize вернет NaN, isPassed вернет false. Это показывает, что форма объявления функции не заменяет валидацию данных - она влияет на структуру кода, а не на бизнес-смысл входа.

Проверь себя: где в этом сценарии логичнее добавить проверку Number.isNaN?

Краткий итог

  • Function Declaration и Function Expression решают схожие задачи, но имеют разное поведение.
  • Declaration поднимается целиком, expression зависит от инициализации переменной.
  • Выбор формы влияет на архитектуру, читаемость и порядок использования.
  • Важно не смешивать формы хаотично и учитывать контекст модуля.
  • Понимание различий снижает ошибки, связанные с hoisting и порядком выполнения.