Przejdź do treści

Jak działają call, apply i bind w JavaScript

Trzy metody na Function.prototype z tym samym celem - ustawić this. Różnice są w (a) czy wywołują od razu, (b) jak podajesz argumenty. Krótki przegląd, kiedy której użyć.

call, apply i bind to trzy metody na Function.prototype. Wszystkie trzy istnieją po to samo - żebyś mógł ustawić wartość this w funkcji wprost, niezależnie od tego, jak została wywołana. To trzecia z czterech reguł bindingu opisanych w poście o this - tzw. explicit binding.

Różnią się dwoma rzeczami: czy wywołują funkcję od razu, i jak podajesz argumenty.

MetodaKiedy wywołujeArgumentyCo zwraca
call(this, ...)natychmiastpo przecinkuwartość zwracana z funkcji
apply(this, [])natychmiastjako tablicawartość zwracana z funkcji
bind(this, ...)nie wywołuje - tworzy nową fnpo przecinkunowa funkcja z this na stałe

Mała demonstracja:

function greet(greeting, punctuation) {
  console.log(`${greeting}, ${this.name}${punctuation}`);
}

const adam = { name: "Adam" };

greet.call(adam, "Cześć", "!"); // → "Cześć, Adam!"
greet.apply(adam, ["Cześć", "!"]); // → "Cześć, Adam!"

const greetAdam = greet.bind(adam, "Cześć");
greetAdam("!"); // → "Cześć, Adam!"

call i apply różnią się tylko składnią argumentów. bind działa inaczej: nie wywołuje funkcji, tylko zwraca nową, w której this jest powiązany na stałe. To tzw. hard binding - raz zbindowanej funkcji nie da się już „odbindować”:

const bound = greet.bind(adam, "Cześć", "!");
bound.call({ name: "Ewa" }); // → "Cześć, Adam!" (call ignorowany dla this)

#Kiedy której użyć

W modern JS te metody widzisz rzadko - większość ich klasycznych przypadków użycia wyparła nowsza składnia.

  • call - praktycznie tylko gdy potrzebujesz wywołać funkcję raz z konkretnym this i nie chcesz tworzyć nowej referencji.
  • apply - prawie nieużywany. Kiedyś służył do rozbicia tablicy na argumenty (Math.max.apply(null, [1, 2, 3])), ale od ES2015 wystarczy spread (Math.max(...[1, 2, 3])).
  • bind - najczęstszy z trójki. Używasz, gdy chcesz wytworzyć wersję funkcji z permanentnym this dla późniejszego callbacka. W klasach reagujących na DOM events alternatywą jest arrow-as-property (i jest częściej używana w nowoczesnym kodzie).

W praktyce: jeśli piszesz w 2026 i nie pracujesz na starym kodzie, bind zobaczysz okazjonalnie, call czasem, apply prawie wcale.

#Ciekawostka historyczna

Stary pattern, który warto rozumieć tylko do czytania starszego kodu:

// Dawniej, gdy arguments było jedyną opcją w funkcji bez parametrów rest:
function legacy() {
  const args = Array.prototype.slice.call(arguments);
  // ...
}

// Dziś:
function modern(...args) {
  // args od razu jest prawdziwą tablicą
}

Method borrowing przez call na prototypie ma już niewielki sens - [...arguments] albo rest parameters załatwiają sprawę.

← Wróć do notatek