this: контекст вызова, bind, call, apply
🔍 Что такое this и почему это важно?
В JavaScript this — это контекст вызова функции. Он определяет, в каком окружении выполняется функция, и может меняться в зависимости от того, как и где её вызывают.
const user = {
name: 'Саша',
greet() {
console.log(`Привет, я ${this.name}!`);
}
};
user.greet(); // Привет, я Саша!
Здесь this ссылается на объект user, потому что метод greet вызван в его контексте. Но что, если мы извлечём метод?
const greetFunc = user.greet;
greetFunc(); // Привет, я undefined!
Ой-ой! Теперь this потерялся. Почему? Потому что функция вызвана без контекста.
🎯 Четыре правила определения this
-
Вызов метода объекта →
this= объект перед точкой
obj.method()→this=obj -
Обычный вызов функции →
this=undefined(в strict mode) или глобальный объект
function() {}()→this=undefined -
Конструктор (
new) →this= новый созданный объект
new User()→this= свежий экземплярUser -
Явное указание через
call,apply,bind→this= переданный объект
function showName() {
console.log(this.name);
}
const person1 = { name: 'Аня' };
const person2 = { name: 'Ваня' };
showName.call(person1); // Аня
showName.call(person2); // Ваня
🛠️ Инструменты управления контекстом: call, apply, bind
call и apply — срочный вызов с нужным this
Оба метода вызывают функцию с указанным контекстом, но различаются передачей аргументов:
function introduce(greeting, punctuation) {
console.log(`${greeting}, я ${this.name}${punctuation}`);
}
const person = { name: 'Маша' };
// call — аргументы через запятую
introduce.call(person, 'Привет', '!'); // Привет, я Маша!
// apply — аргументы массивом
introduce.apply(person, ['Пока', '...']); // Пока, я Маша...
bind — постоянная привязка контекста
Создаёт новую функцию с навсегда привязанным this:
const boundIntroduce = introduce.bind(person, 'Здравствуйте');
boundIntroduce('!'); // Здравствуйте, я Маша!
💡 Стрелочные функции (
() => {}) не имеют своегоthis! Они берут его из внешнего контекста и игнорируютcall/bind.
🔥 Практика: когда что использовать?
| Ситуация | Инструмент | Пример |
|---|---|---|
| Нужно вызвать функцию сейчас | call / apply |
logger.call(context, data) |
Коллбэк с фиксированным this |
bind |
button.addEventListener('click', this.handleClick.bind(this)) |
| Метод класса в React | bind в конструкторе или стрелочная функция |
this.handleClick = this.handleClick.bind(this); |
🎮 Пример: гибкий таймер
class Timer {
constructor(seconds) {
this.seconds = seconds;
this.tick = this.tick.bind(this); // Фиксируем контекст!
}
tick() {
this.seconds--;
console.log(`Осталось: ${this.seconds} сек.`);
}
start() {
setInterval(this.tick, 1000);
}
}
const timer = new Timer(5);
timer.start(); // Корректно уменьшает seconds каждую секунду
Без bind this.tick потерял бы контекст при вызове через setInterval.
🏆 Главное в трёх пунктах:
thisзависит от способа вызова функции.- Управлять контекстом можно через
call,apply,bind. - Стрелочные функции не имеют
thisи используют внешний контекст.
Теперь ты готов укротить this в любом проекте! 🚀 Попробуй применить эти знания в своём коде уже сегодня.