Zasada działania metody bind()
opiera się na istniejących
metodach call()
i apply()
. Funkcja bind()
różni się od call()
w jednym aspekcie — w sumie w najważniejszym!
call()
& apply()
Wyżej wymienione funkcje uruchamiają od razu funkcję na której są uruchomione.
Przykład poniżej:
var book = {
title: "Pan Tadeusz"
};
var computer = {
title: "MacBook"
};
function getTitle(prefix) {
return prefix + this.title;
}
console.log(getTitle.call(book, 'To jest: ')); // "To jest: Pan Tadeusz"
console.log(getTitle.call(computer, 'To jest: ')); // "To jest: MacBook"
console.log(getTitle.apply(book, ['To jest: '])); // "To jest: Pan Tadeusz"
console.log(getTitle.apply(computer, ['To jest: '])); // "To jest: MacBook"
Obie funkcje oczekują pierwszego argumentu, którym będzie kontekst,
czyli nowy świat jaki będzie dostępny, gdy w funkcji getTitle()
będziemy
chcieli pobrać coś z this
-a.
Słowo kluczowe this
wskazuje na kontekst uruchomienia funkcji, w której jest użyty.
bind()
Funkcja z nagłówka zmienia kontekst używany w naszej funkcji.
Ważne jest to, że jej nie uruchamia, tak jak robią to metody
call()
i apply()
. Funkcja bind()
zwraca tą samą funkcję, zmieniając jej
świat oraz ewentualnie definiując wartości oczekiwanych parametrów.
Przykład użycia:
function printStatus() {
console.log(this.isAvailable);
}
var contact = {
isAvailable: true
};
printStatus(); // undefined
var printContactStatus = printStatus.bind(contact);
printContactStatus(); // true
Ale u mnie nie działa!
Podejrzewam, że używasz starej przeglądarki. Bardzo starej.
Tutaj jest dostępna tablica ze wsparciem danego feature-a w przeglądarkach. Jak widzisz, cały rekord jest zielony. Oznacza to, że wszystkie przeglądarki wymienione w nagłówkach mają wsparcie do tej nowości z ES5.
W starszych przeglądarkach metoda bind()
niestety nie istnieje,
ale istnieje prosta implementacja przedstawiona poniżej.
Wystarczy, że uruchomimy kod zdefiniowany poniżej i już nasz kod
z bind()
zadziała.
if (!Function.prototype.bind) {
Function.prototype.bind = function (that) {
var method = this;
var slice = Array.prototype.slice;
var args = slice.apply(arguments, [1]);
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0])));
};
};
}
Powyższy kod to tzw. polyfill — czyli rozwiązanie, które tworzy brakujące API.