← Назад к вопросам
Чем будет отличаться this у function declaration и function expression?
1.0 Junior🔥 181 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Отличия this между function declaration и function expression
Основные отличия
this в JavaScript зависит от контекста вызова, а не от способа объявления функции. Однако есть важные нюансы:
1. Function Declaration (обычная функция)
function greet() {
console.log(this);
}
// Вызов в глобальном контексте
greet(); // this = window (браузер) или global (Node.js)
// Вызов как метод объекта
const obj = { greet };
obj.greet(); // this = obj
// Явное определение контекста
greet.call({ name: "Alice" }); // this = { name: "Alice" }
2. Function Expression (обычная функция-выражение)
const greet = function() {
console.log(this);
};
// Поведение **идентично** function declaration
greet(); // this = window
obj.greet(); // this = obj
3. Стрелочная функция (Arrow Function)
Здесь ключевое отличие! Стрелочная функция не имеет собственного this:
const greetArrow = () => {
console.log(this);
};
// this берётся из **лексического окружения**
greetArrow(); // this = this из внешней области
obj.greetArrow(); // this НЕ МЕНЯЕТСЯ! Остаётся из лексического контекста
const person = {
name: "Bob",
greet: () => {
console.log(this); // this = window, не person!
}
};
person.greet(); // this = window (ошибка!)
Сравнительная таблица
| Способ | this при прямом вызове | this как метод | bind/call/apply |
|---|---|---|---|
| function declaration | window/global | объект | работает ✅ |
| function expression | window/global | объект | работает ✅ |
| стрелочная функция | из лексического контекста | из лексического контекста | не работает ❌ |
Практические примеры
Проблема со стрелочными функциями в объектах
class Counter {
count = 0;
// ❌ Неправильно
increment = () => {
this.count++; // this = объект Counter ✅
};
// ✅ Правильно для методов
decrement() {
this.count--;
};
}
const counter = new Counter();
const { increment } = counter;
increment(); // Всё ещё работает! this привязан к Counter
Event Listeners
// ❌ Проблема с function declaration
button.addEventListener("click", function() {
console.log(this); // this = button элемент
this.disabled = true; // Работает
});
// ✅ Правильно со стрелочной в замыкании
button.addEventListener("click", () => {
console.log(this); // this = объект из внешнего контекста
});
Вывод
- Function Declaration vs Function Expression: почти идентичны в плане
this, оба зависят от контекста вызова - Стрелочные функции: не имеют собственного
this, используют лексический контекст - Правило: используй обычные функции для методов объектов, стрелочные для колбэков и замыканий