call, apply и bind — в чём разница?

Три способа вручную задать контекст функции — и когда какой нужен.

call и apply вызывают функцию с заданным this сразу. bind возвращает новую функцию с привязанным this, не вызывая её.

call: аргументы через запятую

function greet(greeting) {
  return greeting + ", " + this.name;
}

const user = { name: "Аня" };
console.log(greet.call(user, "Привет"));

Вывод:

Привет, Аня

apply: аргументы массивом

apply делает то же, что call, но аргументы передаются массивом. Запомнить помогает «apply — array».

function sum(a, b, c) {
  return a + b + c + " от " + this.name;
}

const ctx = { name: "калькулятор" };
console.log(sum.apply(ctx, [1, 2, 3]));

Вывод:

6 от калькулятор

bind: новая функция на потом

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

const obj = {
  name: "Сервис",
  getName() { return this.name; },
};

const detached = obj.getName;
const bound = obj.getName.bind(obj); // зафиксировали this

console.log(bound());
console.log([0].map(bound)[0]); // даже как коллбэк помнит obj

Вывод:

Сервис
Сервис

Сравнение

МетодВызывает сразу?Аргументы
callдачерез запятую
applyдамассивом
bindнет, возвращает функциючерез запятую

Практический приём: заимствование метода

Через call можно «одолжить» метод одного объекта для другого. Классика — превратить «похожий на массив» объект в массив.

function listArgs() {
  // arguments — массивоподобный, но не массив
  const real = Array.prototype.slice.call(arguments);
  return real.map((x) => x * 2);
}

console.log(listArgs(1, 2, 3));

Вывод:

[ 2, 4, 6 ]

Итог

  • call и apply вызывают функцию сразу; разница лишь в форме аргументов.
  • bind возвращает новую функцию с зафиксированным this — для коллбэков.
  • Через call удобно «заимствовать» методы у других объектов.
Проверьте себя
1. Чем bind отличается от call и apply?
Abind вызывает функцию сразу
Bbind возвращает новую функцию с привязанным this, не вызывая её
Cbind работает только с массивами
DМежду ними нет разницы
2. Как передаются аргументы в apply?
AЧерез запятую
BМассивом
CТолько один аргумент
DЧерез объект
3. Зачем чаще всего применяют bind?
AЧтобы ускорить функцию
BЧтобы зафиксировать this для коллбэка, где контекст иначе теряется
CЧтобы превратить функцию в строку
DЧтобы удалить аргументы
Поддержать проект