Яка різниця між декларацією функції (function declaration) та функціональним виразом (function expression)?
Відкрити окрему відповідьКоротка відповідь
juniorФункція‑декларація — це оголошення, яке піднімається (hoisted), а функціональний вираз — це присвоєння, яке не піднімається. Декларація доступна до оголошення, вираз — лише після виконання. ```js function foo() {} const bar = function() {}; ```
Повне пояснення
Що це і навіщо
- Функція‑декларація (
function foo() {}) створює іменовану функцію, що піднімається до початку блоку. Функціональний вираз (const bar = function() {}) створює анонімну функцію, що зберігається у змінній.
Ключові принципи/терміни
- Hoisting: декларації піднімаються, вирази — ні.
- Scope: обидва працюють у лексичному контексті, але доступність різна.
Як це працює
- Під час фазування парсера декларації розпізнаються і створюються в середовищі виконання. Вирази залишаються у коді і створюються лише під час виконання.
Практика та реалізація
- У випадку, коли потрібна рання доступність функції, використовуйте декларацію. Якщо потрібно передати функцію як аргумент або зберегти її у змінній, використовуйте вираз.
Тестування
- При написанні юніт‑тестів можна перевірити, що декларація доступна до виклику:
test('declaration hoisting', () => {
expect(typeof foo).toBe('function');
});
- Для виразу треба викликати після оголошення:
test('expression after declaration', () => {
const result = bar();
expect(result).toBeDefined();
});
Оптимізація, типові помилки та edge cases
- Помилка «Cannot access 'bar' before initialization» виникає, коли викликають вираз до його оголошення.
- Декларація не піддається «temporal dead zone» і тому безпечніша для раннього виклику.
Диагностика та відладка
- Якщо функція не працює, перевірте порядок оголошень: декларація має бути доступна до виклику, вираз — після.
- Використовуйте
console.log(typeof foo)іtypeof barдля перевірки типу.
Часті помилки
- Виклик виразу до оголошення → «ReferenceError».
- Заміна декларації на вираз у глобальному контексті → «undefined».
- Неочікуване підняття декларації у функційному блоці → «hoisting».
- Перевантаження імені функції та змінної → «conflict».
- Використання
varзамістьconst/letу виразі → «function expression hoisted». - Забудь про
returnу функціональному виразі → «undefined». - Неправильне використання
thisу анонімній функції → «wrong context». - Перевантаження глобального об’єкта
Function→ «security risk».