Bind
The this
keyword plays a vital role in JavaScript. In JavaScript, this is based on how a function was called and not where it was declared (arrow functions behave the other way around).
Let's take an example to demonstrate the this
keyword.
const sayGreeting = {
name: "Parwinder",
hello: function() {
return `Hello, ${this.name}`;
}
}
console.log(sayGreeting.hello()); // Hello, Parwinder
The hello
method can access the name
property of the object sayGreeting
. When I ran the method, it is prefixed by sayGreeting.
and hence it runs in the context of sayGreeting
object.
Instead if I did this:
const sayGreeting = {
name: "Parwinder",
hello: function() {
return `Hello, ${this.name}`;
}
}
const hello = sayGreeting.hello;
console.log(hello === sayGreeting.hello); // true
console.log(hello()); // Hello, undefined
Even though the variable hello
is equal to the method on sayGreeting
, the variable is not executed in the context of sayGreeting
. It is executed in the window
or global context.
bind
allows us to bind context. It creates a new function where the this
keyword is set to what we pass to bind
method.
To make the above example, I can use the bind
method to bind the context of sayGreeting
to hello
variable.
const sayGreeting = {
name: "Parwinder",
hello: function() {
return `Hello, ${this.name}`;
}
}
const hello = sayGreeting.hello.bind(sayGreeting);
console.log(hello()); // Hello, Parwinder
Where do we need to bind in real life?
In all the above example, the data being accessed and the function trying to access it is in the same object. There are times when you want to borrow method from an object but run it in the context of another.
const sayGreeting = {
name: "Parwinder",
hello: function () {
return `Hello, ${this.name}`;
}
}
const nameObject = {
name: "Lauren"
}
const hello = sayGreeting.hello.bind(nameObject);
console.log(hello()); // Hello, Lauren
I have the hello
method in sayGreeting
object. There is no need to recreate it in nameObject
. I can borrow the hello
method and run it in the context of nameObject
.
Call
call()
and apply()
differs from bind()
. bind()
returns a new function whereas call()
and apply()
invoke the existing function immediately. call()
takes this
as the first argument and then it allows you to pass arguments one by one. These arguments would be passed to the function we called.
const sayGreeting = {
name: "Parwinder",
hello: function () {
return `Hello, ${this.name}`;
}
}
console.log(sayGreeting.hello.call(sayGreeting)); // Hello, Parwinder
With arguments:
const sayGreeting = {
name: "Parwinder",
hello: function (trait, color) {
return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;
}
}
console.log(sayGreeting.hello.call(sayGreeting, "like", "red"));
// Hello, Parwinder. I see you like red. It is my favorite too!
Apply
apply()
even though executes the function immediately like call()
does but it takes an array of arguments as a second parameter instead of comma-separated values.
const sayGreeting = {
name: "Parwinder",
hello: function () {
return `Hello, ${this.name}`;
}
}
console.log(sayGreeting.hello.apply(sayGreeting)); // Hello, Parwinder
No difference between apply
and call
when done without arguments. But, when used with arguments.
const sayGreeting = {
name: "Parwinder",
hello: function (trait, color) {
return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;
}
}
console.log(sayGreeting.hello.apply(sayGreeting, ["like", "red"]));
// Hello, Parwinder. I see you like red. It is my favorite too!
apply
makes it easier to send n number of arguments in an array. Sending multiple arguments is easier now in ES6 by using the rest (...) operator.
Top comments (6)
Nice. Definitely important functions to understand. My understanding of how prototypal βinheritanceβ works is that call is used when an object calls function from further up the chain, does that sound about right?
I would say the method is
call
ed when you are not adjacent or you are detached from the method you arecall
ing.call
serves an extremely important purpose of running a method under a context you provide.This means that we can call any function, explicitly specifying the reference that
this
should reference in the calling function.I guess what I am getting it as if you had an array called xs and you called map on that array, would you in effect be calling Array.prototype.map.call(xs,function)? Since map doesnβt belong to xs. I know I am being very specific here π
I use the mnemonic Apply = Array to remember the difference
Bind I have used a few times. Call and Apply never. Need to find more use cases for my own projects thanks for sharing.
You are not alone. The need for
call
andapply
is rarely there. Bind is used fairly often in vanilla JS or if you are working with React.