DEV Community

Cover image for Call, Bind And Apply in JavaScript with pollyfills.
vedanth bora
vedanth bora

Posted on

Call, Bind And Apply in JavaScript with pollyfills.

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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);
  };
};

Enter fullscreen mode Exit fullscreen mode

apply

The apply() method is similar to call() method but calls the specified function with a given thisvalue, and argumentsprovided 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

Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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);
};

Enter fullscreen mode Exit fullscreen mode

Hope this blog helped you understand the difference between call() bind() and apply().

Top comments (0)