← Назад к вопросам
Как при написании this понимаешь что будет нужный объект?
2.3 Middle🔥 275 комментариев
#JavaScript Core
Комментарии (5)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение значения this в JavaScript
Одна из самых сложных частей JavaScript — понимание, на что указывает this в каждый момент времени. Это зависит от того, как функция вызвана, а не где она определена.
Правило 1: Правило вызова (Call Site Rule)
Главное правило: смотри, ГДЕ вызвана функция, а не где она определена. this определяется в момент вызова.
// Объект
const obj = {
name: "Alice",
greet: function() {
console.log(this.name); // this указывает на obj
}
};
obj.greet(); // Вывод: Alice
// Почему: функция вызвана как obj.greet(), this = obj
// Но если присваиваешь функцию переменной...
const greetFn = obj.greet;
greetFn(); // Вывод: undefined
// Почему: функция вызвана как greetFn(), this = window (или undefined в strict mode)
// Потеря контекста!
Правило 2: Неявный контекст (Implicit Binding)
Когда функция вызывается как метод объекта, this указывает на этот объект.
const user = {
name: "Bob",
age: 25,
displayInfo: function() {
console.log(this.name, this.age);
}
};
user.displayInfo(); // this = user
// Вывод: Bob 25
// Но если вложить функцию...
const user2 = {
name: "Carol",
details: {
info: function() {
console.log(this.name); // this = details объект, не user2
}
}
};
user2.details.info(); // this указывает на details, не user2
// Вывод: undefined (у details объекта нет name)
Правило 3: Явный контекст (Explicit Binding)
Используй call(), apply(), bind() для явного указания this.
function introduce() {
console.log("Меня зовут " + this.name);
}
const person1 = { name: "Dave" };
const person2 = { name: "Eve" };
// call() — вызвать с явным this
introduce.call(person1); // Вывод: Меня зовут Dave
introduce.call(person2); // Вывод: Меня зовут Eve
// apply() — как call, но аргументы в массиве
function greetWithAge(age) {
console.log(this.name + " возраст " + age);
}
greetWithAge.apply(person1, [30]); // Вывод: Dave возраст 30
// bind() — создаёт новую функцию с привязанным this
const boundGreet = introduce.bind(person1);
boundGreet(); // Вывод: Меня зовут Dave
boundGreet(); // Можно вызывать много раз
// Полезно для обработчиков событий
class Button {
constructor(label) {
this.label = label;
// Привязываем this раз при конструировании
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this.label + " нажата");
}
render() {
return <button onClick={this.handleClick}>{this.label}</button>;
}
}
Правило 4: Стрелочные функции (Arrow Functions)
Стрелочные функции НЕ имеют своего this. Они берут this из внешней области видимости.
// Обычная функция
const obj1 = {
name: "Frank",
regularFunction: function() {
console.log(this.name); // this = obj1
},
arrowFunction: () => {
console.log(this.name); // this = window (или undefined)
}
};
obj1.regularFunction(); // Вывод: Frank
obj1.arrowFunction(); // Вывод: undefined
// В методе с регулярной функцией стрелочная берёт this из метода
const obj2 = {
name: "Grace",
outerMethod: function() {
console.log("Outer:", this.name); // this = obj2
const innerArrow = () => {
console.log("Inner:", this.name); // this = obj2 (из outerMethod)
};
innerArrow(); // Вывод: Inner: Grace
}
};
obj2.outerMethod();
// Стрелочная функция НЕ подходит для методов объекта
const obj3 = {
name: "Henry",
greet: () => {
console.log(this.name); // НЕПРАВИЛЬНО! this = window
}
};
obj3.greet(); // Вывод: undefined
Правило 5: Конструктор (Constructor)
Когда функция вызвана с new, this указывает на новый объект.
function User(name) {
this.name = name;
this.greet = function() {
console.log("Привет, " + this.name);
};
}
const user1 = new User("Ivan");
user1.greet(); // Вывод: Привет, Ivan
// this = user1
// Класс (ES6) — это синтаксический сахар для конструктора
class Person {
constructor(name) {
this.name = name; // this = создаваемый объект
}
greet() {
console.log("Привет, " + this.name);
}
}
const person = new Person("Julia");
person.greet(); // Вывод: Привет, Julia
Как я определяю this на практике
// ТЕХНИКА: Следи по цепочке вызовов
// Пример 1: Простой вызов
function test() {
console.log(this);
}
test(); // this = undefined (strict mode) или window
// Пример 2: Метод объекта
const obj = { test: test };
obj.test(); // this = obj
// Пример 3: setTimeout с обычной функцией
const obj2 = {
name: "Kevin",
delay: function() {
setTimeout(function() {
console.log(this.name); // this = window, потеря контекста
}, 100);
}
};
obj2.delay(); // Вывод: undefined
// Исправление 1: Стрелочная функция
const obj3 = {
name: "Laura",
delay: function() {
setTimeout(() => {
console.log(this.name); // this = obj3
}, 100);
}
};
obj3.delay(); // Вывод: Laura
// Исправление 2: bind
const obj4 = {
name: "Mike",
delay: function() {
setTimeout(function() {
console.log(this.name); // this = obj4 (благодаря bind)
}.bind(this), 100);
}
};
obj4.delay(); // Вывод: Mike
Практическое правило для быстрого определения
Когда видишь this, спроси себя:
- Это стрелочная функция? — Используй this из внешней области
- Есть точка перед функцией (obj.method)? — this = obj
- Есть call(), apply() или bind()? — this = первый аргумент
- Есть new? — this = новый объект
- Иначе — this = window (или undefined в strict mode)
Итого
Определение this:
- Неявный — через точку (obj.method -> this = obj)
- Явный — call(), apply(), bind()
- Стрелочные — берут this из внешней области
- Конструктор — new создаёт this
- По умолчанию — window или undefined
Главное: смотри на МЕСТО ВЫЗОВА, не на место определения.