У JavaScript функцію можна створити кількома способами, і вони відрізняються не лише синтаксисом.
// оголошення функції (function declaration)
function add(a, b) {
return a + b;
}
// функціональний вираз (function expression)
const multiply = function (a, b) {
return a * b;
};
// стрілкова функція (arrow function)
const square = (n) => n * n;
1. Підняття (hoisting). Оголошення функції доступне до рядка, де воно написане, - рушій «піднімає» його на початок області видимості:
greet(); // працює
function greet() { console.log('Привіт'); }
sayHi(); // TypeError: sayHi is not a function (з var)
var sayHi = function () {};
wave(); // ReferenceError (з const/let)
const wave = () => {};
Вирази й стрілкові функції - це значення, присвоєні змінним, тож діють правила змінних: з const/let до ініціалізації звертатися не можна.
2. this. Звичайні функції отримують this залежно від способу виклику. Стрілкові функції власного this не мають - беруть його з місця, де їх створено. Тому стрілки зручні в колбеках усередині методів класу, але не підходять як методи об'єкта, яким потрібен this цього об'єкта.
3. Інші відмінності стрілкових функцій:
- немає об'єкта
arguments(використовують rest-параметри...args); - не можна викликати з
new- вони не конструктори; - короткий запис з неявним поверненням:
(n) => n * 2. Щоб повернути об'єкт, його беруть у дужки:() => ({ id: 1 }).
Що обирати:
- оголошення функції - для «іменованих» функцій верхнього рівня модуля: їх зручно читати й шукати, і порядок у файлі не важливий;
- стрілкові функції - для колбеків (
map,filter, обробники подій) і коротких допоміжних функцій; - методи класів і об'єктів - звичайний синтаксис методу
save() { ... }.
Іменований функціональний вираз (const f = function factorial(n) { ... }) має ім'я, видиме лише всередині, - для рекурсії й читабельних стеків помилок.