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.
| Metoda | Kiedy wywołuje | Argumenty | Co zwraca |
|---|---|---|---|
call(this, ...) | natychmiast | po przecinku | wartość zwracana z funkcji |
apply(this, []) | natychmiast | jako tablica | wartość zwracana z funkcji |
bind(this, ...) | nie wywołuje - tworzy nową fn | po przecinku | nowa 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 konkretnymthisi 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 permanentnymthisdla 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ę.