Learn JavaScript

Function declaration vs function expression в JavaScript

В JavaScript функцию можно создать разными способами. Два самых базовых - function declaration и function expression. Они похожи, но ведут себя по-разному из-за hoisting (поднятия объявлений).

Function declaration (объявление функции)

Function declaration - это функция, объявленная отдельной инструкцией.

function sum(a, b) {
  return a + b;
}

console.log(sum(2, 3)); // 5

Главная особенность: можно вызвать до объявления

Объявления функций поднимаются (hoisting) целиком. Поэтому вызов сработает даже выше по коду.

console.log(sum(2, 3)); // 5

function sum(a, b) {
  return a + b;
}

Это удобно для “верхнеуровневого” кода, где сначала читается список функций, а потом детали.

Function expression (функциональное выражение)

Function expression - это когда функция создается как значение и присваивается переменной.

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

console.log(sum(2, 3)); // 5

Важная особенность: нельзя вызвать до присваивания

Переменная sum существует, но сама функция появится только после выполнения строки присваивания. Если вызвать раньше, будет ошибка.

// console.log(sum(2, 3)); // ReferenceError (если sum объявлена через const/let)

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

Если использовать var, поведение будет другим (из-за hoisting переменных), но это обычно не используют в современном коде.

// console.log(sum(2, 3)); // TypeError: sum is not a function

var sum = function (a, b) {
  return a + b;
};

Сравнение по пунктам

1) Синтаксис

  • declaration: function name() { ... }
  • expression: const name = function () { ... }

2) Hoisting

  • declaration: можно вызывать до объявления
  • expression: нельзя вызывать до строки присваивания

3) Где удобно использовать

  • declaration: функции верхнего уровня, утилиты, чистые функции
  • expression: функции как значения (передача в другие функции, колбэки, условия)

Функция как значение: почему expression часто встречается

В JavaScript функции - значения. Их можно передавать как аргументы и возвращать из других функций. Поэтому function expression (и стрелочные функции) встречаются постоянно, особенно в методах массивов и обработчиках событий.

Пример: передача функции в другую функцию.

function run(fn) {
  return fn(10);
}

const double = function (n) {
  return n * 2;
};

console.log(run(double)); // 20

Именованные function expression

У function expression может быть имя. Оно нужно в основном для удобства отладки (например, имя видно в стеке вызовов).

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

console.log(factorial(5)); // 120

Снаружи доступно имя переменной factorial, а имя fact используется внутри функции.

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

Практичное правило для начала:

  • Если нужна “обычная” функция, которую удобно вызывать в любом месте файла - подходит function declaration.
  • Если функция используется как значение (колбэк, аргумент, возвращаемое значение) - часто выбирают function expression (или стрелочную функцию).

Оба варианта нормальны. Важно понимать разницу в hoisting, чтобы не получить ошибку “не могу вызвать функцию”.

Что стоит запомнить

  • Function declaration поднимается целиком, ее можно вызывать до объявления.
  • Function expression создается при выполнении строки присваивания, поэтому раньше вызвать нельзя.
  • Функции в JavaScript - значения, поэтому expression часто используется для колбэков и передачи функций.