Gunnari Auvinen's Blog

Call vs. Apply in JavaScript

November 13, 2014

Both call and apply allow you to invoke a specific function and pass in a context, that will be this within the function, as well as arguments. How you pass in the arguments for each method is different though and can certainly lead to frustration as you work to debug your code. Having spent some time debugging my own code due to this confusion, I figured it was worthwhile to write a blog post about it for reference, even if I’m the only one that refers to it in the future!

Call

As stated previously call allows you to invoke a function, pass in your desired context as the first argument, as well as your input arguments. In the case of the call method, you pass in the arguments individually and separated by commas.

One instance where it can be beneficial to use call is when creating subclasses within JavaScript. Specifically if your subclass shares traits with your superclass, you can use call on the superclass to set the properties on the subclass. Here’s a quick example.

var Business = function(name, location) {
  this.name = name;
  this.location = location;
};

var Restaurant = function(name, location, type) {
  Business.call(this, name, location);
  this.category = 'Restaurant';
  this.type = type;
};

Restaurant.prototype = Object.create(Business.prototype);
Restaurant.prototype.constructor = Restaurant;

var SupplyStore = function(name, location, type) {
  Business.call(this, name, location);
  this.category = 'Supply Store'
  this.type = type;
};

SupplyStore.prototype = Object.create(Business.prototype);
SupplyStore.prototype.constructor = SupplyStore;

var pizza = new Restaurant('House of Slices', 'Your Neighborhood', 'Pizza');
var officeSupplies = new SupplyStore('All Your Office Supply Needs', 'Next town over', 'Office Supply Store');

Another quick example of using call is when you can use it to convert the arguments array of a function input from an array-like object to an array.

var addNumbers = function() {
  var inputs = Array.prototype.slice.call(arguments, 0);
  return inputs.reduce(function(previous, current) {
    return previous + current;
  }, 0);
};

var total = addNumbers(1, 2, 3, 4);
console.log(total); // 10

Apply

Now that I’ve discussed call, you might wonder how apply is any different, as they ostensibly do the same thing. apply still takes a context as its first argument, but instead of taking individual arguments after that, apply takes an array or array-like object instead.

In this somewhat contrived example, if you wanted to print out the character code for each letter in an array of unknown length, you could use apply to invoke that function.

var testStringChars = 'hello there!'.split('');
var printCharacters = function() {
  for (var i = 0; i < arguments.length; i++) {
    console.log('character code for "' + arguments[i] + '" is ' + String.prototype.charCodeAt.call(arguments[i]));
  }
};

printCharacters.apply(this, testStringChars);

Takeaway

The main takeaway here is that both call and apply both allow you to invoke functions and supply the context that it should be invoked with. The fundamental difference between the two is how the input arguments are passed in when invoked. call takes its input arguments as individual inputs, while apply takes an array or array-like object. If you have a good example for apply please let me know!


Gunnari Auvinen

Written by Gunnari Auvinen who works at Turo. The opinions expressed here are his own. You should follow him on Medium.