this, call, apply, bind, стрелочные функции

↑ 1.4 JavaScript: основы · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: junior

Зачем это на собесе

«Чему равен this?» — обязательная задача. Знайте четыре правила и особенности стрелочных функций.

Объяснение

this определяется способом вызова, а не местом объявления (кроме стрелочных функций).

Правило (по приоритету)this
new Foo()новый объект
call/apply/bindуказанный объект
obj.method()obj
простой вызов fn()undefined (strict) / window
const user = { name: "A", hi() { return this.name; } };
user.hi();                  // "A"
const f = user.hi;
f();                        // undefined: контекст потерян
 
f.call(user);               // "A"
f.apply(user, [arg1]);      // аргументы массивом
const bound = f.bind(user); // новая функция с привязанным this
bound();                    // "A"
 
class Btn {
  label = "OK";
  onClick = () => console.log(this.label);   // стрелка: this от класса
  handle() { console.log(this.label); }
}
btn.addEventListener("click", new Btn().handle);   // this потерян (будет элемент)

Стрелочные функции: своего this, arguments, super, new.target нет — берут из внешней лексической области. Нельзя вызывать через new, call/apply/bind не меняют this.

Во Vue this в Options API — инстанс компонента (автобиндинг методов); в Composition API this не используется.

Нюансы и подводные камни

  • Коллбэки (setTimeout(obj.method), arr.map(this.fn)) теряют контекст.
  • Стрелка как метод объекта берёт this внешнего контекста (не объект).
  • bind создаёт новую функцию каждый раз — сравнивайте и снимайте обработчики с сохранённой ссылкой.
  • В обработчиках DOM для обычных функций this — элемент (currentTarget).

Практика

  1. Определите this в 10 примерах вызовов.
  2. Реализуйте свой bind (см. полифиллы).
  3. Исправьте потерю контекста в классе тремя способами.

Вопросы с ответами

Связанные темы