Intro
In this article, we will discuss three of the most important concepts in JavaScript: call
, bind
and apply
along with their pollyfils. We will see how these concepts can be used to write better code.
Call
The call()
method is used to call a function with a given this
value and arguments provided individually.
For example, consider the following code:
const personDetails = {
name: 'Jane',
hello(age) {
console.log("Hello " this.name + '! age:' + age);
},
};
console.log(personDetails.hello("21")); // Hello, Jane! age: 21
But what if we wanted to call the hello()
function with a different this
value, in other words with a different object / context. We can use the call()
method to do this
const personDetails = {
name: 'Jane',
hello(age) {
console.log("Hello " this.name + '! age:' + age);
},
};
const newPersonDetails = {
name: 'John',
};
console.log(personDetails.hello.call(newPersonDetails, "26)); // Hello, John! age: 26
As we can see, the call()
method takes two arguments: the first argument is the value of this
, and the second argument is the age that should be used in the hello()
function.
Let’s take a look at some more examples to understand this better.
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
const cheese = new Food('feta', 5);
const fun = new Toy('robot', 40);
pollyfill for call
This pollyfil for bind is fairly simple, its a function with takes the context or this
value and the arguments the function should be called with and executes the function
Function.prototype.myCall = function (obj = {}, ...args) {
if (typeof this !== 'function') {
throw new Error(this + ' cannot be bound as this is not callable');
}
obj.fn = this;
obj.fn(...args); // call the function with the args and the context provided
};
Bind
The bind()
method creates a new function that, when called, has its this
keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
For example, consider the following code:
const personDetails = {
name: 'Jane',
hello(age) {
console.log("Hello " this.name + '! age:' + age);
},
};
const newPersonDetails = {
name: 'John',
};
const newPersonDetailsHello = personDetails.hello.bind(newPersonDetails, "26")
console.log(newPersonDetailsHello()) // Hello, John! age: 26
Lets take a look at a few more example to understand better
this.x = 9; // 'this' refers to the global object (e.g. 'window') in non-strict mode
const module = {
x: 81,
getX() {
return this.x;
},
};
module.getX();
// returns 81
const retrieveX = module.getX;
retrieveX();
// returns 9; the function gets invoked at the global scope
// Create a new function with 'this' bound to module
// New programmers might confuse the
// global variable 'x' with module's property 'x'
const boundGetX = retrieveX.bind(module);
boundGetX();
// returns 81
Copy to Clipboard
Pollyfill for bind
The polyfill for bind is similar to call only difference is that it returns a function which is called with the this
value and arguments provided
Function.prototype.myBind = function (obj = {}, ...args) {
if (typeof this !== 'function') {
throw new Error(this + ' cannot be bound as this is not callable');
}
obj.fn = this;
return () => {
return obj.fn(...args);
};
};
apply
The apply()
method is similar to call()
method but calls the specified function with a given this
value, and arguments
provided as an array.
For example, consider the following code:
const personDetails = {
name: 'Jane',
hello(age) {
console.log("Hello " this.name + '! age:' + age);
},
};
const newPersonDetails = {
name: 'John',
};
console.log(personDetails.hello.call(newPersonDetails, ["26"])); // Hello, John! age: 26
Lets take a look at a more examples
const array = ["a", "b"];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
pollyfill for apply
The polyfill for bind is similar to call()
only difference arguments provided are in array
Function.prototype.myApply = function (obj = {}, args = []) {
if (typeof this !== 'function') {
throw new Error(this + ' cannot be bound as this is not callable');
}
obj.fn = this;
obj.fn(...args);
};
Hope this blog helped you understand the difference between call()
bind()
and apply()
.
Top comments (0)