Metody: bind, call, apply w JavaScript
Obiekty w JavaScript posiadają swoje właściwości oraz metody. Można bezpośrednio w obiekcie zapisać metodę, która następnie będzie wywoływana. To by jednak oznaczało, że jeżeli na obiekcie potrzebujemy wywołać kilka metod wszystkie muszą się w nim pojawić. Jeszcze gorszym przypadkiem jest posiadanie wielu obiektów i w każdym z nich wywoływanie tych samych metod [wersja (1) na poniższym wykresie].
Rozwiązaniem tego problemu, są właśnie metody call, bind, apply. Każda z nich pozwala nam połączyć metodę z obiektem czyli podać funkcji dane do pracy. Dzięki temu jak widać na poniższej grafice nie mnożymy metod (Function A i B, są użyte do różnych obiektów).
Bind()
Call() i Apply()
Najpierw przykład bez użycia metod bind, call, apply
Obiekt, w którym jedna metoda w całości została wrzucona do jego wnętrza, a druga przypisana (obie jak widać robią to samo).
var car0 = {
name: "toyota",
year: 2012,
doors: 3,
color: "black",
show: showcar,
show2: function showthiscar(more) {
return console.log( this.name + " " + this.year + " " + this.doors + " " + this.color + " - " + more);
}
}
function showcar(more) {
return console.log( this.name + " " + this.year + " " + this.doors + " " + this.color + " - " + more);
}
car0.show("auto Oli - cała metoda w obiekcie");
car0.show2("auto Jana - przypisanie metody w obiekcie");
Wywołanie jest proste jednak w kodzie zrobił się straszny śmietnik. Przy większej liczbie obiektów oraz metod trudno byłoby się na dłuższą metę w tym połapać. Gdybyśmy jeszcze chcieli pisać aplikację w modelu MVC to taka praktyka jest już całkowicie zakazana.
O wiele lepiej można to zrobić z użyciem metod: Bind() Call() Apply()
var car1 = {
name: "mazda",
year: 2015,
doors: 5,
color: "red",
}
var car2 = {
name: "volvo",
year: 2016,
doors: 4,
color: "white"
}
function showcar(more) {
return console.log( this.name + " " + this.year + " " + this.doors + " " + this.color + " - " + (more || ""));
}
Bind()
Najpierw przypisanie do zmiennej, a następnie wywołanie z podaniem w nawiasie argumentu.
var some = showcar.bind(car1);
some("auto Jacka - bind car1");
var some2 = showcar.bind(car2);
some2("auto Jacka - bind car2");
Call() i Apply() bez argumentów
Jeżeli nie dodajemy, żadnych argumentów to nie ma między nimi różnicy:
showcar.call(car1);
showcar.apply(car2);
Call() z argumentami
showcar.call(car1, "auto Marka - call car1");
showcar.call(car2, "auto Marka - call car2");
Apply() z argumentami
showcar.apply(car1, ["auto Joli - apply car1"]);
showcar.apply(car2, ["auto Joli - apply car2"]);
Efekt działania powyższego, który widoczny będzie w konsoli przeglądarki.