Как определяется this? Четыре правила
Как понять, чему равно this в любом куске кода.
this определяется не там, где функция объявлена, а тем, как она вызвана. Исключение — стрелочные функции (о них отдельный урок).
Четыре правила (по приоритету)
- new —
thisэто новый создаваемый объект. - Явная привязка —
call/apply/bindзадаютthisвручную. - Вызов как метод —
obj.method():thisэтоobj(то, что слева от точки). - Обычный вызов — просто
fn():thisэтоundefinedв строгом режиме (или глобальный объект в нестрогом).
Правило «что слева от точки»
Самое частое: при вызове как метод this равен объекту перед точкой. Стоит «оторвать» метод от объекта — и контекст теряется.
"use strict";
const user = {
name: "Аня",
greet() { return "Привет, " + this.name; },
};
console.log(user.greet()); // this === user
const fn = user.greet; // оторвали от объекта
try {
console.log(fn()); // this потерян
} catch (e) {
console.log(e.name);
}
Вывод:
Привет, Аня TypeError
В строгом режиме ("use strict") при обычном вызове this равен undefined, поэтому this.name бросает TypeError. Без строгого режима this стал бы глобальным объектом, а this.name — undefined: тоже потеря контекста, просто тихая. Современные модули по умолчанию строгие.
Вызов с new
При new создаётся новый объект, и this внутри функции указывает на него.
function User(name) {
this.name = name;
}
const u = new User("Боря");
console.log(u.name);
Вывод:
Боря
Потеря this в коллбэке
Классическая ловушка: передаём метод как коллбэк, и this теряется, потому что вызов происходит уже без объекта слева.
const obj = {
value: 10,
show() { return this.value; },
};
const arr = [1];
const r = arr.map(obj.show); // вызов без obj слева
console.log(r[0]); // this не obj
Вывод:
undefined
Итог
thisзависит от способа вызова, а не от места объявления.- Приоритет:
new→ явная привязка → метод объекта → обычный вызов. - «Оторванный» от объекта метод теряет контекст — частый источник багов.
Проверьте себя
1. От чего зависит значение this в обычной функции?
AОт места, где функция объявлена
Bthis всегда равен глобальному объекту
CОт способа, которым функция вызвана
DОт имени функции
2. Чему равен this при вызове obj.method()?
Aundefined
BГлобальному объекту
CСамой функции method
DОбъекту obj (то, что слева от точки)
3. Что чаще всего происходит при передаче метода объекта как коллбэка?
Athis теряется, потому что вызов идёт без объекта слева
Bthis остаётся прежним объектом
CВозникает синтаксическая ошибка
DМетод копируется вместе с объектом