Learn & Solve : call(), apply() and bind() methods in JavaScript

romeo11
785 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

call(), apply() and bind() Methods in JavaScript.

Working with JavaScript “this” keyword can be tricky. Not knowing the background rules may end up with the famous “it works, but I don’t know why” or worse: “it doesn’t work and I don’t know why”. It’s good to know the theory before putting things into practice. Call(), Apply() and Bind() methods can come in handy when setting the “this” value.

Basic rules worth remembering:
  1. “this” always refers to an object.
  2. “this” refers to an object which calls the function it contains.
  3. In the global context “this” refers to either window object or is undefined if the ‘strict mode’ is used.
var car = { 
    registrationNumber: "GA12345",
    brand: "Toyota",

    displayDetails: function(){
        console.log(this.registrationNumber + " " + this.brand);
    }
}

The above will work perfectly fine as long as we use it this way:

car.displayDetails(); // GA12345 Toyota

But what if we want to borrow a method?

var myCarDetails =  car.displayDetails;
myCarDetails();

Well, this won’t work as the “this” will be now assigned to the global context which doesn’t have neither the registrationNumber nor the brand property.

The bind() Method

For such cases we can use the ECMAScript 5 bind() method of the Function.prototype property. This means bind() can be used by every single function.

var myCarDetails = car.displayDetails.bind(car); 
myCarDetails(); // GA12345 Toyota

The bind() method creates a new function where “this” refers to the parameter in the parenthesis in the above case “car”. This way the bind() method enables calling a function with a specified “this” value.

What if we would like to pass a parameter to the displayDetails function? We can use the bind method again. The following argument of the bind() method will provide an argument to the function bind() is called on.

Let me rewrite the car object:

var car = { 
    registrationNumber: "GA12345",
    brand: "Toyota",

    displayDetails: function(ownerName){
        console.log(ownerName + ", this is your car: " + this.registrationNumber + " " + this.brand);
    }
}

Example of passing arguments with bind():

var myCarDetails = car.displayDetails.bind(car, "Vivian"); // Vivian, this is your car: GA12345 Toyota

call() and apply() methods

Similar but slightly different usage provide the call() and apply() methods which also belong to the Function.prototype property.

This time there is a car object without the displayDetails function, which is located in the global context.

var car = { 
    registrationNumber: "GA12345",
    brand: "Toyota"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your car: " + this.registrationNumber + " " + this.brand);
}

We can use the apply() function:

displayDetails.apply(car, ["Vivian"]); // Vivian, this is your car: GA12345 Toyota

Or

displayDetails.call(car, "Vivian"); // Vivian, this is your car: GA12345 Toyota

Note that when using the apply() function the parameter must be placed in an array. Call() accepts both an array of parameters and a parameter itself. Both are great tools for borrowing functions in JavaScript.

bind(), call() and apply() functions can make your life easier when you need to set the value of ‘this’. Hope the post was helpful.

You can visit for learning ES6 : https://rapides6.herokuapp.com

Learning Exercise !!!

1
2
3
4
5
var func = function() {
console.log(this)
}.bind(1);
func();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
var func = function() {
console.log(this)
}.bind(1);
var obj = {
callFun : func
}
obj.callFun.func();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
function checkFun(a, b, c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
checkFun.call(1,2,3,4);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
function checkFun(a, b, c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
checkFun.apply(1,[2,3,4]);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
return total;
}
var sum = sumOfNumbers(1,2,3);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
return total;
}
var sum = sumOfNumbers.call(null,1,2,3);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
10
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
return total;
}
var numbers = [1,2,3];
var sum = sumOfNumbers.apply(null, numbers);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
function updateZipCode() {
console.log(this)
}
updateZipCode.call(1);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
var updateZipCode = function () {
console.log(this);
};
updateZipCode.call({});
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
var updateZipCode = function () {
console.log(this);
};
updateZipCode.call({ zip: '11787'});
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
var updateZipCode = function () {
console.log(this);
};
var zipCode = {
zip: '11787'
};
updateZipCode.call(zipCode);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
var updateZipCode = function (newZip, country) {
console.log(newZip + ' ' + country);
};
var zipCode = {
zip: '11787'
};
updateZipCode.call(zipCode, '11888', 'us');
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
var updateZipCode = function (newZip, country) {
console.log(newZip + ' ' + country);
};
var zipCode = {
zip: '11787'
};
updateZipCode.apply(zipCode, ['11888', 'us']);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
10
11
"use strict";
var zipcode = {
checkZipcode : function() {
console.log(this);
function updateZipCode() {
console.log(this);
}
updateZipCode.call(this);
}
}
zipcode.checkZipcode();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
10
11
"use strict";
var zipcode = {
checkZipcode : function() {
console.log(this);
var updateZipCode = function() {
console.log(this);
}.bind(this);
updateZipCode();
}
}
zipcode.checkZipcode();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"use strict";
var person = {
name : "Jack",
prop : {
name : "Daniel",
getName : function() {
return this.name;
}
}
}
var name = person.prop.getName.bind(person);
console.log(name());
var name = person.prop.getName();
console.log(name);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Open Source Your Knowledge: become a Contributor and help others learn. Create New Content