call(), apply и bind в JavaScript — простое руководство и шпаргалка

Введение
В JavaScript у функций есть скрытый контекст исполнения — this. Методы call, apply и bind позволяют явно указать, чему будет равен this при выполнении функции. Это важно при переиспользовании методов объектов, при привязке обработчиков событий или при передачe функций как колбэков.
Краткое определение терминов:
- this — ссылка на объект, в контексте которого выполняется функция.
- контекст выполнения — набор значений (включая this), доступных во время вызова функции.
Как работает call
Метод call вызывает функцию сразу и явно задаёт значение this. Последующие параметры передаются по списку.
Пример:
let obj = {
name: "John",
surname: "Doe",
getFullName: function() {
console.log(this.name + " " + this.surname);
}
};
obj.getFullName(); // John Doe
const obj2 = {
name: "Jane",
surname: "Doe"
};
obj.getFullName.call(obj2); // Jane Doe
// С аргументами
let obj3 = {
name: "John",
surname: "Doe",
getFullName: function(age, gender) {
console.log(this.name + " " + this.surname + " " + age + " " + gender);
}
};
obj3.getFullName.call(obj2, 21, "female"); // Jane Doe 21 femaleСовет: используйте call, когда нужно выполнить функцию немедленно с заданным this и набором отдельных аргументов.
Как работает apply
apply почти идентичен call, но принимает аргументы в виде массива. Это удобно, когда параметры уже собраны в массив или их число динамическое.
Пример:
const obj = {
name: "John",
surname: "Doe",
getFullName: function(age, gender) {
console.log(this.name + " " + this.surname + " " + age + " " + gender);
}
};
const obj2 = {
name: "Jane",
surname: "Doe"
};
obj.getFullName.apply(obj2, [21, "female"]); // Jane Doe 21 femaleСовет: используйте apply при вызове с массивом аргументов (например, при применении Math.max к массиву чисел).
Как работает bind
bind возвращает новую функцию с захваченным (привязанным) значением this. Исходная функция не вызывается немедленно.
Пример:
const obj = {
name: "John",
surname: "Jane",
getFullName: function() {
console.log(this.name + " " + this.surname);
}
};
const obj2 = {
name: "Jane",
surname: "Doe"
};
let func = obj.getFullName.bind(obj2);
func(); // Jane DoeПрименение: useful при передаче методов как колбэков (setTimeout, обработчики событий), чтобы сохранить нужный контекст.
Шпаргалка (cheat sheet)
- call(thisArg, arg1, arg2, …)
- apply(thisArg, [arg1, arg2, …])
- bind(thisArg, arg1?, arg2?, …) — возвращает новую функцию
Когда использовать:
- Вызвать немедленно с отдельными аргументами → call
- Вызвать немедленно с массивом аргументов → apply
- Передать функцию на будущее с фиксированным this → bind
Ментальные модели и эвристики
- Представьте функцию как «машину», а this как «панель управления». call/apply вставляют панель и запускают машину сразу. bind вставляет панель и возвращает управляемую машину для запуска позже.
- Если аргументы уже в массиве — применяйте apply. Если нет — call удобнее.
Когда эти методы не пригодятся (контрпример)
- При стрелочных функциях. Стрелочные функции не имеют собственного this; привязка через bind/call/apply не изменит их this.
- При методах, уже связанных через bind — повторный bind не изменит привязку.
Пример со стрелочной функцией:
const arrow = () => console.log(this);
arrow.call({a:1}); // this останется лексическим, а не {a:1}Альтернативные подходы
- Использование замыканий для захвата контекста вместо bind.
- Трансформация кода на классы/ES6 и сохранение ссылок через свойства экземпляра.
- Для асинхронных колбэков можно сохранять контекст в переменной: const self = this.
Рольовой чеклист для интервью
- Навыки собеседуемого:
- Объяснить разницу между call, apply и bind.
- Показать кодовый пример для каждого метода.
- Объяснить поведение со стрелочными функциями.
- Показать практическое применение (обработчики событий, переиспользование методов).
Простые тест-кейсы и критерии приёмки
- Кейс 1: функция объекта вызывается на другом объекте через call → this должен ссылаться на целевой объект.
- Кейс 2: функция вызывается через apply с массивом аргументов → аргументы корректно переданы.
- Кейс 3: bind возвращает функцию, которая при вызове использует привязанный this.
- Кейс 4: попытка изменить this стрелочной функции через bind → this не меняется.
Критерии приёмки:
- Все четыре кейса выполняют ожидаемые логи в консоли.
- Нет ошибок типов при передаче undefined/ null как thisArg (поведение описано в спецификации: глобальный объект или undefined в строгом режиме).
Краткая справка и подводные камни
- В строгом режиме передача null/undefined в call/apply оставит this равным null/undefined; в нестрогом режиме это приведёт к глобальному объекту (window в браузере).
- bind создаёт новый объект функции; сравнение оригинальной и привязанной функции вернёт false.
- При передаче метода объекта как колбэка без привязки this потеряется — используйте bind или стрелочную функцию.
Сравнение в двух строках
- call — вызвать сейчас + аргументы по списку.
- apply — вызвать сейчас + аргументы массивом.
- bind — вернуть функцию с привязанным this для вызова позже.
Однострочный глоссарий
- call/apply/bind — методы Function.prototype для управления значением this.
Важно: стрелочные функции не имеют собственного this и игнорируют эти методы.
Заключение
Методы call, apply и bind — простые, но мощные инструменты для контроля контекста исполнения функций в JavaScript. Понимание их отличий и областей применения помогает писать более предсказуемый и переиспользуемый код. На интервью часто спрашивают примеры и поведение со стрелочными функциями — подготовьте короткие демонстрации и несколько практических сценариев применения.
Summary:
- call вызывает функцию сразу, аргументы по списку.
- apply вызывает функцию сразу, аргументы массивом.
- bind возвращает новую функцию с фиксированным this.
Notes:
- Проверяйте поведение в строгом/нестрогом режиме при передаче null/undefined.
- Используйте bind для колбэков и событий, apply для переменных списков аргументов.
Похожие материалы
YouTube замедляет Firefox — что делать
Как разместить простой сайт на Dropbox
Как складывать зарядные кабели, чтобы не повредить их
Сохранить вложения Gmail в Google Drive