В 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 часто используется для колбэков и передачи функций.