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

romeo11
85.1K views

## 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 !!!

var func = function() {
console.log(this)
}.bind(1);
func();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var func = function() {
console.log(this)
}.bind(1);
var obj = {
callFun : func
}
obj.callFun.func();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function checkFun(a, b, c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
checkFun.call(1,2,3,4);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function checkFun(a, b, c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
checkFun.apply(1,[2,3,4]);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
}
var sum = sumOfNumbers(1,2,3);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
}
var sum = sumOfNumbers.call(null,1,2,3);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function sumOfNumbers() {
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
}
var numbers = [1,2,3];
var sum = sumOfNumbers.apply(null, numbers);
console.log(sum);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function updateZipCode() {
console.log(this)
}
updateZipCode.call(1);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var updateZipCode = function () {
console.log(this);
};
updateZipCode.call({});
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var updateZipCode = function () {
console.log(this);
};
updateZipCode.call({ zip: '11787'});
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var updateZipCode = function () {
console.log(this);
};
var zipCode = {
zip: '11787'
};
updateZipCode.call(zipCode);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var updateZipCode = function (newZip, country) {
console.log(newZip + ' ' + country);
};
var zipCode = {
zip: '11787'
};
updateZipCode.call(zipCode, '11888', 'us');
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
var updateZipCode = function (newZip, country) {
console.log(newZip + ' ' + country);
};
var zipCode = {
zip: '11787'
};
updateZipCode.apply(zipCode, ['11888', 'us']);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
"use strict";
var zipcode = {
checkZipcode : function() {
console.log(this);
function updateZipCode() {
console.log(this);
}
updateZipCode.call(this);
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
"use strict";
var zipcode = {
checkZipcode : function() {
console.log(this);
var updateZipCode = function() {
console.log(this);
}.bind(this);
updateZipCode();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
"use strict";
var person = {
name : "Jack",
prop : {
name : "Daniel",
getName : function() {
return this.name;
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX