> Что такое call, apply и bind в JavaScript и в чем их разница (JavaScript)

Уровень: junior · Роль: frontend · Категория: Технические вопросы

Компании: Kvando Technologies, ООО Премиум ИТ Солюшен, IT-One, EPAM, Exness, TYMY, Globaldrive

Стек: JavaScript

> Пример ответа

Короткий ответ

call, apply и bind - это методы функций в JavaScript, которые позволяют явно задать значение this при вызове. call и apply вызывают функцию немедленно, разница только в передаче аргументов: call принимает их списком, apply - массивом. bind не вызывает функцию, а возвращает новую функцию с привязанным this и, опционально, фиксированными аргументами. Основное применение - заимствование методов и создание функций с предзаданным контекстом.

Подробное объяснение

В JavaScript значение this определяется тем, как вызвана функция, а не где она объявлена. Это часто приводит к потере контекста, особенно при передаче метода как callback. Методы call, apply и bind дают контроль над этим поведением.

call(thisArg, arg1, arg2, ...) - вызывает функцию с указанным this и аргументами, переданными через запятую. Выполняется сразу.

apply(thisArg, [argsArray]) - аналогичен call, но аргументы передаются в виде массива или массивоподобного объекта. Удобен, когда аргументы уже находятся в массиве.

bind(thisArg, arg1, arg2, ...) - возвращает новую функцию, у которой this навсегда привязан к thisArg. Аргументы, переданные в bind, также фиксируются и добавляются в начало списка аргументов при вызове. Исходная функция не изменяется.

Ключевое отличие: call и apply - это одноразовые вызовы, а bind создает переиспользуемую функцию. bind также поддерживает частичное применение (каррирование) - можно зафиксировать часть аргументов заранее.

Важно: bind не изменяет исходную функцию, а возвращает новую. Привязка через bind не может быть переопределена последующими call или apply - новая функция всегда будет использовать заданный this.

На практике

Наиболее частые сценарии использования:

  • Заимствование методов: например, Array.prototype.slice.call(arguments) для преобразования arguments в настоящий массив.
  • Сохранение контекста в callback: setTimeout(this.handleClick.bind(this), 1000) - гарантирует, что внутри handleClick this будет указывать на нужный объект.
  • Частичное применение: const multiplyByTwo = multiply.bind(null, 2) - создает новую функцию с фиксированным первым аргументом.
  • Функциональное программирование: передача методов как функций высшего порядка без потери контекста.

В современном JavaScript часто используют стрелочные функции для сохранения лексического this, но bind остается полезным, когда нужно создать переиспользуемую функцию с привязкой.

Пример кода

JAVASCRIPT
const user = {
name: 'Анна',
greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
};
const admin = { name: 'Петр' };
// call - немедленный вызов, аргументы списком
user.greet.call(admin, 'Привет', '!'); // "Привет, Петр!"
// apply - немедленный вызов, аргументы массивом
user.greet.apply(admin, ['Здравствуйте', '!']); // "Здравствуйте, Петр!"
// bind - возвращает новую функцию
const greetAdmin = user.greet.bind(admin, 'Добрый день');
greetAdmin('?'); // "Добрый день, Петр?"
// Частичное применение через bind
const greetAnna = user.greet.bind(user, 'Привет');
greetAnna('!'); // "Привет, Анна!"

Как отвечать на собеседовании

Начните с краткого определения всех трех методов. Затем подчеркните главное различие: call и apply вызывают функцию сразу, bind возвращает новую. Обязательно упомяните разницу в передаче аргументов между call и apply. Приведите один-два примера из практики - заимствование методов или сохранение контекста в callback. Если спросят про современные альтернативы, скажите про стрелочные функции, но отметьте, что bind незаменим для частичного применения. Говорите уверенно, без лишних деталей, но покажите понимание, зачем это нужно.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание того, как работает this в JavaScript и почему теряется контекст.
  • Знание синтаксических различий между тремя методами.
  • Умение выбрать правильный метод под конкретную задачу.
  • Осведомленность о частичном применении через bind.
  • Понимание ограничений: bind не изменяет исходную функцию, привязку нельзя переопределить.

Типичные ошибки

  • Путаница между call и apply - забывают, что apply принимает массив.
  • Утверждение, что bind вызывает функцию - это не так, он возвращает новую.
  • Попытка переопределить this у функции, созданной через bind, с помощью call или apply - это не сработает.
  • Забывают, что bind поддерживает частичное применение аргументов.
  • Использование bind там, где достаточно стрелочной функции, - не ошибка, но показывает непонимание современных подходов.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью