Чем отличаются `call`, `apply` и `bind`?

MiddleJavaScript · Frontend·Обновлено 21 июня 2026
Коротко
call и apply немедленно вызывают функцию с заданным this, отличаясь лишь способом передачи аргументов: call — через запятую, apply — массивом. bind возвращает новую функцию с привязанным this, не вызывая её сразу.

Общая идея

Все три метода позволяют явно задать контекст выполнения функции — то есть указать, чем будет являться this внутри неё. Они определены на Function.prototype и доступны у любой функции.

call

Вызывает функцию немедленно. Первый аргумент — контекст (this), остальные — аргументы функции, перечисленные через запятую.

function greet(greeting, punctuation) {
  // this.name берётся из переданного контекста
  console.log(`${greeting}, ${this.name}${punctuation}`);
}

const user = { name: 'Алексей' };
greet.call(user, 'Привет', '!'); // Привет, Алексей!

apply

Работает идентично call, но аргументы функции передаются вторым параметром в виде массива (или массивоподобного объекта). Удобен, когда аргументы уже собраны в массив.

greet.apply(user, ['Здравствуйте', '.']); // Здравствуйте, Алексей.

// Классический приём — нахождение максимума в массиве
const numbers = [3, 1, 4, 1, 5, 9];
const max = Math.max.apply(null, numbers); // 9
// Сегодня чаще используют spread: Math.max(...numbers)

bind

Не вызывает функцию. Возвращает новую функцию с намертво привязанным this (и, опционально, с частично зафиксированными аргументами — карринг). Привязанный this нельзя переопределить повторным call/apply/bind.

const greetAlexey = greet.bind(user, 'Привет');
greetAlexey('!');  // Привет, Алексей!
greetAlexey('?');  // Привет, Алексей?

// Типичный случай — сохранение контекста для колбэка
class Timer {
  constructor() {
    this.seconds = 0;
    // без bind this внутри tick будет undefined (strict) или window
    setInterval(this.tick.bind(this), 1000);
  }
  tick() {
    this.seconds++;
  }
}

Сравнительная таблица

call apply bind
Вызов немедленный немедленный отложенный
Аргументы перечислением массивом перечислением (частично)
Возвращает результат функции результат функции новую функцию
Переопределить this потом можно можно нельзя

Когда что использовать

  • call — одноразовый вызов с известными аргументами и нужным контекстом.
  • apply — аргументы уже в массиве или нужно передать динамический набор.
  • bind — колбэки, обработчики событий, передача метода как функции первого класса, частичное применение аргументов.

Важно про стрелочные функции

Стрелочные функции не имеют собственного this — все три метода не могут изменить их контекст. bind вернёт обёртку, но this внутри стрелки останется тем, каким был при создании.

Что хочет услышать интервьюер

Кандидат чётко объясняет разницу: call/apply вызывают функцию немедленно, bind — нет

Понимает разницу в передаче аргументов между call (перечислением) и apply (массивом)

Знает, что bind возвращает новую функцию и фиксирует this навсегда

Может назвать практические сценарии применения каждого метода (колбэки, spread-замена apply и т.д.)

Упоминает, что стрелочные функции игнорируют все три метода в плане this

Пример: call, apply и bind на одном примере

interface User {
  name: string;
}

function introduce(role: string, company: string): string {
  // this типизируется через ThisParameterType
  return `Я ${(this as User).name}, ${role} в ${company}`;
}

const alice: User = { name: 'Алиса' };

// call — аргументы через запятую, немедленный вызов
console.log(introduce.call(alice, 'разработчик', 'PurpleSchool'));
// 'Я Алиса, разработчик в PurpleSchool'

// apply — аргументы массивом, немедленный вызов
console.log(introduce.apply(alice, ['тимлид', 'PurpleSchool']));
// 'Я Алиса, тимлид в PurpleSchool'

// bind — возвращает новую функцию, this зафиксирован
const introduceAlice = introduce.bind(alice);
console.log(introduceAlice('ментор', 'PurpleSchool'));
// 'Я Алиса, ментор в PurpleSchool'

// Частичное применение через bind
const introduceAsDev = introduce.bind(alice, 'разработчик');
console.log(introduceAsDev('Yandex'));
// 'Я Алиса, разработчик в Yandex'

// Стрелочная функция — bind не меняет this
const arrow = () => (globalThis as unknown as { tag: string }).tag ?? 'global';
const bound = arrow.bind({ tag: 'игнорируется' });
console.log(bound()); // 'global' — this стрелки неизменяем

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

Путают порядок: говорят, что apply принимает аргументы через запятую, а call — массивом

Считают, что bind вызывает функцию немедленно, а не возвращает новую

Не знают, что повторный bind или call на результат bind не меняет this

Забывают о частичном применении аргументов (карринге) через bind

Не упоминают стрелочные функции и их игнорирование явного контекста

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее