bind vs call vs apply
Original blog post at: giulioambrogi.com/blog/2017/09/25/bind-vs-call-vs-apply/.
Bind, call and apply are three methods provided by JavaScript that allow us to control the value that this references to.
As you may already know every function gets this property assigned automagically. However in some circumstances we may want to specifically set its value, overriding the default behaviour.
Here’s when bind, call and apply come in help. Let’s see how they work and how they are different from each other.
bind()
bind returns a clone of the targeted function with the custom this assigned to it. Then we'll need to call that function to see this feature in action.
var vehicle = {
wheels: 4,
getWheels: function(type) {
console.log("I'm a "+type+" and I have "+ this.wheels + " wheels");
}
}
var getWheels_2 = vehicle.getWheels.bind({ wheels: 2}, "motorbyke");
getWheels_2(); //I'm a motorbyke and I have 2 wheels
vehicle.getWheels("bla") //I'm a bla and I have 4 wheels
A big pro here is that we can potentially call getWheels_2 multiple times without having to assign our this again.
At line 9, getWheels_2‘s this is the one we’ve binded, so this.wheels is going to be 2.
Line 10 is only meant to demonstrate that the original function was not modified by bind, indeed it prints out the original this.wheels value (4).
call()
Call is really similar to bind but it works in a different way: it lets us specify what this should reference right when invoking the function. In other words, it doesn’t returns any new function - despite what bind does - and invokes the targeted function attaching the new this value.
var vehicle = {
wheels: 4,
getWheels: function(type) {
console.log("I'm a "+type+" and I have "+ this.wheels + " wheels");
}
}
vehicle.getWheels.call({ wheels: 3 }, "side car"); //I'm a side car and I have 3 wheels
vehicle.getWheels("subaru"); //I'm a subaru and I have 4 wheels
At line 8 you can see how this reference gets changed by call. Line 9 - as shown above for bind - demonstrates how getWheels per se doesn’t get affected by call.
apply()
Then apply is the equivalent of call, but here the difference is the way they accepts parameters:
- call wants the parameters to be passed individually
- apply accepts an array of parameters
var vehicle = {
wheels: 4,
getWheels: function() {
console.log("I'm a "+arguments[0]+" and I have "+ this.wheels + " wheels");
}
}
vehicle.getWheels(["subaru"]); //I'm a subaru and I have 4 wheels
vehicle.getWheels.apply({ wheels: 3 }, ["sidecar"]); //I'm a side car and I have 3 wheels