
В JavaScript значение this определяется способом вызова функции, а не её местом объявления. В методах объекта this ссылается на сам объект, но при передаче метода как колбэка контекст теряется. Чтобы сохранить правильное this, используют функции bind, call и apply.
bind создаёт новую функцию с фиксированным контекстом. Например, для метода объекта, передаваемого в обработчик события, вызов obj.method.bind(obj) гарантирует, что this останется равным obj. call и apply выполняют функцию сразу с указанным this, различие в передаче аргументов: call – через запятую, apply – через массив.
Стрелочные функции не имеют собственного this и наследуют его из внешнего контекста. Это удобно при работе с вложенными функциями или промисами: внешнее значение this сохраняется без дополнительного привязывания. В обработчиках событий или асинхронных колбэках стрелочные функции упрощают код и предотвращают ошибки.
Для одноразовых вызовов лучше использовать call или apply. Для передачи методов в обработчики или сохранения контекста в колбэках применяют bind или стрелочные функции. Правильный выбор метода передачи this делает код предсказуемым и облегчает отладку сложных объектов и цепочек вызовов.
Как работает this в обычных функциях

В обычных функциях значение this определяется контекстом вызова, а не местом объявления. Оно не привязано к функции автоматически, в отличие от стрелочных функций.
Основные правила:
- При вызове функции напрямую:
thisссылается на глобальный объект (windowв браузере,globalв Node.js). В строгом режиме'use strict'thisбудетundefined. - При вызове функции как метода объекта:
thisуказывает на объект, через который функция вызвана. - При использовании
callилиapply:thisпринудительно задается первым аргументом. - При использовании
bind: создается новая функция с фиксированнымthis.
Примеры:
- Прямая функция:
- Метод объекта:
- Использование call/apply:
- Использование bind:
function show() {
console.log(this);
}
show(); // window или undefined в строгом режиме
const obj = {
value: 10,
show() {
console.log(this.value);
}
};
obj.show(); // 10
function greet() {
console.log(this.name);
}
const user = { name: 'Anna' };
greet.call(user); // Anna
greet.apply(user); // Anna
function increment() {
this.count++;
}
const counter = { count: 0 };
const boundIncrement = increment.bind(counter);
boundIncrement();
console.log(counter.count); // 1
Рекомендации:
- Используйте строгий режим для предотвращения случайного связывания с глобальным объектом.
- При передаче функций в обработчики событий или таймеры явно привязывайте
thisчерезbind. - Для сохранения контекста внутри вложенных функций можно сохранять
thisв переменную или использовать стрелочные функции.
Передача this через метод call
Метод call позволяет вызвать функцию с явным указанием контекста this. Синтаксис: func.call(context, arg1, arg2, ...), где context – объект, который будет использован как this внутри функции.
Пример:
const user = { name: 'Иван' };
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
greet.call(user, 'Привет'); // Выведет: "Привет, Иван"
Здесь this внутри greet ссылается на объект user.
Если требуется передать несколько аргументов, их можно перечислить через запятую после контекста. call выполняет функцию немедленно, что удобно для разовых вызовов с конкретным this.
Для методов объектов часто используется call при заимствовании функций:
const admin = { name: 'Анна' };
greet.call(admin, 'Здравствуйте'); // "Здравствуйте, Анна"
Так можно использовать одну функцию для разных объектов без дублирования кода.
Важно помнить, что call отличается от apply только способом передачи аргументов: call через список, apply через массив.
Рекомендация: применять call, когда нужно вызвать функцию один раз с определённым this и фиксированным набором аргументов, особенно при работе с функциями вне контекста их объекта.
Использование apply для изменения контекста
Метод apply позволяет вызвать функцию с явно заданным контекстом this и аргументами в виде массива. Это особенно полезно, когда необходимо использовать методы одного объекта для другого объекта без копирования кода.
Синтаксис:
func.apply(context, [arg1, arg2, ...]);
Пример использования:
const user = {
name: 'Алексей',
greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
};
const anotherUser = { name: 'Мария' };
user.greet.apply(anotherUser, ['Привет']); // Выведет: Привет, Мария
Рекомендации по использованию apply:
- Используйте
apply, когда аргументы функции уже находятся в массиве или массивоподобной структуре. - Для вызова с конкретным контекстом предпочтительно использовать
applyвместо присваиванияthisчерез переменную. - Метод подходит для динамического применения функций к различным объектам без дублирования кода.
Пример с массивом аргументов:
function sum(a, b, c) {
return a + b + c;
}
const numbers = [2, 3, 5];
const result = sum.apply(null, numbers); // 10
Особенности:
- Первый аргумент задаёт контекст
this,nullилиundefinedдопустимы, если контекст не нужен. - Второй аргумент должен быть массивом или объектом с индексированными элементами.
applyобеспечивает гибкость при передаче переменного числа аргументов.
bind для закрепления this на объекте

Метод bind создает новую функцию с фиксированным значением this, независимо от того, как она вызывается. Это особенно полезно при передаче методов объектов как колбэков, где this теряет контекст.
Синтаксис: const новаяФункция = оригинальнаяФункция.bind(объект); После этого this внутри новаяФункция всегда будет указывать на указанный объект.
Пример закрепления метода объекта для использования в обработчике события:
const user = {
name: 'Иван',
sayHi() { console.log(this.name); }
};
const boundSayHi = user.sayHi.bind(user);
setTimeout(boundSayHi, 1000); // выведет "Иван"
Метод bind также поддерживает частичное применение аргументов. Например: const sum5 = sum.bind(null, 5); создаст функцию, где первый аргумент фиксирован как 5.
При использовании bind важно помнить, что новая функция имеет отдельный экземпляр и не влияет на оригинал. Это позволяет безопасно передавать методы в асинхронные операции без потери контекста.
Рекомендация: применять bind для всех колбэков, передаваемых в сторонние библиотеки или таймеры, чтобы избежать ошибок undefined в this.
Стрелочные функции и автоматическое наследование this

Стрелочные функции в JavaScript не создают собственный контекст this. Вместо этого они автоматически наследуют this из внешней функции, в которой были объявлены. Это позволяет избегать явного связывания контекста через bind или временные переменные.
Пример: внутри метода объекта стрелочная функция сохранит ссылку на объект, даже если вызов функции будет асинхронным или передан как колбэк:
const obj = {
value: 42,
method() {
setTimeout(() => {
console.log(this.value); // 42
}, 100);
}
};
Использование стрелочных функций в колбэках и обработчиках событий упрощает код и исключает распространённую ошибку, когда this указывает на глобальный объект или undefined. В отличие от обычных функций, здесь не требуется const self = this или bind(this).
Рекомендация: применяйте стрелочные функции везде, где нужно сохранить контекст внешней функции. Для методов, требующих динамического this при вызове, лучше использовать обычные функции.
Важно помнить, что стрелочные функции не подходят для конструкторов, так как они не имеют собственного this и не могут использовать new.
Сохранение this через переменную

В JavaScript значение this внутри вложенной функции по умолчанию не наследует контекст внешней функции. Для сохранения текущего объекта создают переменную, которой присваивают this. Чаще всего используют имена self или that.
Пример:
const user = {
name: ‘Ivan’,
showName: function() {
const self = this;
function logName() {
console.log(self.name); // Ivan
}
logName();
}
};
Рекомендации:
- Использовать понятное имя для переменной, сохраняющей this, чтобы избежать путаницы в коде.
- Применять этот метод при наличии нескольких вложенных функций или колбеков, где стрелочные функции нежелательны.
- Сохраняемая переменная фиксирует контекст объекта независимо от способа вызова вложенной функции.
- Не использовать глобальные переменные для хранения this – нарушается область видимости и повышается риск ошибок.
Метод обеспечивает прямой доступ к свойствам объекта без изменения функций или создания дополнительных оберток.
this в обработчиках событий
В JavaScript значение this в обработчиках событий зависит от способа их назначения. В DOM-элементах при использовании стандартного метода element.addEventListener this внутри функции указывает на элемент, на котором произошло событие.
Пример:
button.addEventListener('click', function() { console.log(this); });
Здесь this ссылается на button. Если использовать стрелочную функцию, this берется из внешнего контекста, что часто приводит к неожиданному поведению.
Для изменения контекста this рекомендуется применять метод bind:
button.addEventListener('click', handler.bind(obj));
В этом случае this внутри handler всегда будет указывать на obj, независимо от элемента, на котором произошло событие.
Ниже таблица демонстрирует различие в поведении this для разных способов назначения обработчиков:
| Способ назначения | Функция | Значение this |
|---|---|---|
| addEventListener с обычной функцией | function() { … } | Элемент, на котором произошло событие |
| addEventListener с стрелочной функцией | () => { … } | Внешний контекст, где функция была объявлена |
| onclick через атрибут HTML | onclick=»func()» | Элемент, на котором назначен обработчик |
| bind | handler.bind(obj) | Явно указанное значение obj |
Для сложных интерфейсов рекомендуется избегать стрелочных функций для обработчиков событий, если требуется работать с конкретным элементом. Метод bind полезен, когда один обработчик должен использовать контекст объекта вне DOM.
Передача this в асинхронных функциях
В асинхронных функциях значение this не всегда сохраняется автоматически. Например, при использовании setTimeout или промисов стандартная функция теряет контекст объекта:
class User {
constructor(name) { this.name = name; }
delayedLog() {
setTimeout(function() { console.log(this.name); }, 1000);
}
}
В этом примере this.name будет undefined, так как обычная функция создаёт собственный контекст. Решение – использовать стрелочную функцию, которая наследует this из внешней области:
setTimeout(() => { console.log(this.name); }, 1000);
При работе с промисами рекомендуется сохранять контекст через стрелочные функции или метод bind. Например:
fetchData() {
apiCall().then(function(result) { console.log(this.name, result); }.bind(this));
}
Стрелочные функции предпочтительнее, так как они уменьшают количество лишнего кода и исключают необходимость bind. В асинхронных методах класса (async) также допустимо применять стрелочные функции внутри тела метода для обращения к свойствам объекта:
async fetchAndLog() {
const data = await apiCall();
const process = () => console.log(this.name, data);
process();
}
Если используется чистая функция без стрелочной формы, всегда можно явно привязать this с помощью bind или сохранить ссылку на контекст в переменной: const self = this; перед асинхронным вызовом.
Главный принцип – контекст асинхронной функции нужно контролировать либо через стрелочные функции, либо через явное связывание bind, чтобы обращаться к свойствам объекта корректно.
Вопрос-ответ:
Что происходит с this внутри обычной функции в JavaScript?
Внутри обычной функции значение this зависит от того, как функция была вызвана. Если функция вызвана напрямую, this ссылается на глобальный объект (window в браузере или global в Node.js). Если функция вызвана как метод объекта, this будет указывать на сам объект. Это поведение иногда вызывает путаницу, особенно при передаче функций как колбэков.
Как стрелочные функции влияют на this?
Стрелочные функции не имеют собственного this. Вместо этого они используют значение this из окружающего контекста, в котором были созданы. Это удобно, например, при работе с методами объектов или внутри обработчиков событий, где обычная функция могла бы потерять ссылку на объект.
Для чего нужны методы call и apply в JavaScript?
Методы call и apply позволяют явно задать значение this для вызова функции. Разница между ними заключается в способе передачи аргументов: call принимает список аргументов через запятую, а apply — массив аргументов. Эти методы полезны, когда нужно использовать одну функцию для разных объектов или при динамическом управлении контекстом.
Как работает метод bind и чем он отличается от call и apply?
Метод bind создаёт новую функцию с фиксированным значением this, которое нельзя изменить при последующих вызовах. В отличие от call и apply, которые вызывают функцию сразу, bind возвращает новую функцию, которую можно вызвать позже. Это особенно удобно, когда нужно передать метод объекта как колбэк, сохранив правильный контекст.
