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
called when you are not adjacent or you are detached from the method you arecalling.callserves 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
thisshould 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
callandapplyis rarely there. Bind is used fairly often in vanilla JS or if you are working with React.