← Назад к вопросам

Чем будет отличаться 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 declarationwindow/globalобъектработает ✅
function expressionwindow/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, используют лексический контекст
  • Правило: используй обычные функции для методов объектов, стрелочные для колбэков и замыканий
Чем будет отличаться this у function declaration и function expression? | PrepBro