Function Declaration vs Function Expression
🎭 Два лица функций: Declaration и Expression
В JavaScript функции — это хлеб и масло программирования. Но знаете ли вы, что они могут объявляться двумя разными способами? Давайте разберёмся, в чём разница и когда что использовать.
// Function Declaration (Объявление функции)
function greet(name) {
return `Привет, ${name}!`;
}
// Function Expression (Функциональное выражение)
const greet = function(name) {
return `Привет, ${name}!`;
};
🕰️ Когда они создаются? Hoisting в действии
Ключевое отличие — в моменте создания:
- Function Declaration «поднимаются» (hoisting) — они доступны до объявления в коде
- Function Expression создаются в момент выполнения строки
// Работает! (Function Declaration)
sayHello();
function sayHello() {
console.log("Hello!");
}
// Ошибка! (Function Expression)
sayGoodbye(); // TypeError: sayGoodbye is not a function
const sayGoodbye = function() {
console.log("Goodbye!");
};
💡 Запомните: Function Declaration — как VIP-персона, которой разрешён ранний вход. Function Expression — обычный посетитель, ждёт своей очереди.
🔄 Гибкость Function Expression
Function Expression открывают больше возможностей:
- Можно присваивать разным переменным
- Можно передавать как аргументы
- Можно создавать анонимные функции «на лету»
// Присваивание
const action = function() { /* ... */ };
// Передача как аргумента
button.addEventListener('click', function() {
console.log('Клик!');
});
// Динамическое создание
const operations = {
add: function(a, b) { return a + b },
multiply: function(a, b) { return a * b }
};
🏷️ Именованные Function Expression
У Function Expression может быть имя — это помогает при отладке:
const factorial = function calculate(n) {
return n <= 1 ? 1 : n * calculate(n - 1);
};
console.log(factorial(5)); // 120
🔍 Имя
calculateдоступно только внутри функции — это как паспорт для внутреннего использования.
🚀 Стрелочные функции — особый вид Expression
Современный ES6-синтаксис стрелочных функций — это разновидность Function Expression:
const square = x => x * x;
const sum = (a, b) => a + b;
const complex = (x, y) => {
const res = x + y;
return res * 2;
};
📌 Особенности стрелочных функций:
- Нет своего this (берёт из внешнего контекста)
- Нельзя использовать как конструктор (нет new)
- Нет своего arguments
🏗️ Где что использовать? Практические рекомендации
| Ситуация | Лучший выбор | Почему? |
|---|---|---|
| Основная логика программы | Function Declaration | Чище код, лучше читаемость |
| Коллбэки, обработчики событий | Function Expression | Часто анонимные, компактный синтаксис |
| Методы объектов | Function Expression | Естественно ложится в структуру |
| Короткие однострочники | Стрелочные функции | Максимальная лаконичность |
🔮 Продвинутые возможности
Function Expression открывают двери в мир функционального программирования:
// Функции высшего порядка
function createMultiplier(factor) {
return function(num) {
return num * factor;
};
}
const double = createMultiplier(2);
console.log(double(5)); // 10
⚠️ Тонкие места и подводные камни
1. Неожиданный this в обычных Function Expression:
const person = {
name: 'Alex',
greet: function() {
console.log('Привет, ' + this.name);
}
};
const greet = person.greet;
greet(); // Ошибка — this потерян!
2. Стрелочные функции решают эту проблему:
const person = {
name: 'Alex',
greet: () => {
console.log('Привет, ' + this.name); // Теперь this берётся из внешнего контекста
}
};
💡 Главные выводы
- Declaration — когда нужна функция в основном потоке кода
- Expression — когда нужна гибкость (аргументы, присваивание)
- Стрелочные — для лаконичности и работы с
this
Попробуйте прямо сейчас переписать какой-нибудь свой код, используя разные формы объявления функций! Как сказал бы Данила Бежин: «Экспериментируйте — это лучший способ понять нюансы».