this, call, apply, bind, стрелочные функции
↑ 1.4 JavaScript: основы · ← Предыдущая · → Следующая
Зачем это на собесе
«Чему равен
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).
Практика
- Определите
thisв 10 примерах вызовов. - Реализуйте свой
bind(см. полифиллы). - Исправьте потерю контекста в классе тремя способами.
Вопросы с ответами
Чем стрелочная функция отличается от обычной по
this?У неё нет собственного
this: она берёт его из внешнего контекста в момент создания.
Чем
callотличается отapplyиbind?
callвызывает сразу с аргументами по одному,apply— с массивом,bindвозвращает новую функцию с привязаннымthis.