Разница между var functionName = function() {} и function functionName() {} в JavaScript
Основное различие: поднятие (hoisting)
Главное отличие между function declaration и function expression заключается в том, как JavaScript обрабатывает их на этапе компиляции. Это называется поднятием (hoisting).
Function Declaration (объявление функции)
Когда вы используете синтаксис function myFunc() {}, вся функция "поднимается" (hoisted) вверх своей области видимости. Это означает, что вы можете вызвать функцию до того, как она объявлена в коде:
// Работает! Функция уже доступна благодаря hoisting
sayHello();
function sayHello() {
console.log("Привет!");
}
JavaScript видит этот код так:
// Функция "поднимается" наверх
function sayHello() {
console.log("Привет!");
}
// Теперь можем её вызвать
sayHello();
Function Expression (функциональное выражение)
Когда вы используете var myFunc = function() {}, поднимается только объявление переменной var myFunc, но не её значение. Переменная будет undefined до момента присваивания:
// Ошибка! myFunc ещё undefined
sayGoodbye(); // TypeError: sayGoodbye is not a function
var sayGoodbye = function() {
console.log("Пока!");
};
// Теперь работает
sayGoodbye(); // "Пока!"
JavaScript видит это так:
// Поднимается только объявление переменной
var sayGoodbye;
// Попытка вызова — sayGoodbye === undefined
sayGoodbye(); // Ошибка!
// Присваивание значения
sayGoodbye = function() {
console.log("Пока!");
};
Когда что использовать?
- Function Declaration — используйте, когда функция должна быть доступна в любой точке кода (например, для рекурсии, callback-функций или глобальных утилит). Это делает код более читаемым, так как порядок объявления не важен.
- Function Expression — используйте, когда:
- Нужно присвоить функцию переменной условно (например, в зависимости от окружения)
- Функция используется как аргумент (callback)
- Вы создаёте анонимные функции
- Нужно контролировать, когда функция становится доступной
Дополнительные отличия
- Именованные function expression — можно дать имя функции даже в выражении:
var myFunc = function namedFunc() {}. Это помогает при отладке (имя появляется в стеке вызовов). - Область видимости — function declaration всегда создаётся в текущей области видимости (глобальной или локальной). Function expression может быть присвоена переменной в любой области.
- Современный синтаксис — в ES6+ часто используют
constилиletвместоvarдля function expression:const myFunc = () => {}(стрелочная функция). Это даёт блочную область видимости и предотвращает случайное переопределение.
Пример для наглядности
// Function Declaration — можно вызвать до объявления
result1 = double(5); // 10
function double(x) {
return x * 2;
}
// Function Expression — вызов до объявления вызовет ошибку
// result2 = triple(5); // TypeError
const triple = function(x) {
return x * 3;
};
result2 = triple(5); // 15 — теперь работает
В современных проектах (React, Node.js) чаще используют function expression с const и стрелочные функции, так как это даёт больше контроля и предсказуемости. Но function declaration остаётся отличным выбором для "корневых" функций, которые должны быть доступны везде.
Практические рекомендации и подводные камни
Коллега выше отлично объяснил теорию. Я добавлю несколько практических моментов, которые помогут избежать ошибок в реальных проектах.
1. Условное объявление функций
С function declaration нельзя создать функцию условно — это приведёт к неожиданному поведению:
// Плохо: function declaration в блоке if
if (true) {
function sayHi() { console.log("Hi"); }
} else {
function sayHi() { console.log("Bye"); }
}
// В некоторых браузерах сработает последнее объявление!
Правильный подход — использовать function expression:
let sayHi;
if (condition) {
sayHi = function() { console.log("Hi"); };
} else {
sayHi = function() { console.log("Bye"); };
}
2. Рекурсия и именованные выражения
Если вам нужна рекурсия внутри function expression, используйте именованное выражение:
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1);
};
// Имя fact доступно только внутри функции
3. Стрелочные функции (ES6+)
В современном JavaScript стрелочные функции () => {} стали стандартом для function expression. Они короче и не имеют своего this, что упрощает работу в классах и обработчиках событий:
const sum = (a, b) => a + b;
const numbers = [1, 2, 3].map(n => n * 2);
Итог
Для новичков: используйте function declaration для основных функций, которые не зависят от условий. Для всего остального (колбэки, обработчики, модули) — function expression или стрелочные функции. Это сделает код предсказуемым и читаемым.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги