JS: .call vs. .apply

Published on: November 30, 2014

Tags: js and interview-questions

What’s the difference between .call and .apply?

Let’s start with the similarities.

What are .call and .apply?

Both methods allow you to invoke a function and pass parameters through.

1
2
3
4
5
6
function printer(message) {
    console.log(message)
}

printer.call({}, "hello") // logs "hello"
printer.apply({}, "world!") // logs "world!"

Wow. Awesome. A more verbose way to invoke functions. Fantastic. Why not just use printer("hello")?

Well actually, .call and .apply can do more than simply invoke a method, they can also pass through context. Here’s an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(name){
    this.name = name;
    this.introduceSelf = function() {
        console.log("Hello, my name is " + this.name);
    }
}

var alice = new Person('Alice');
alice.introduceSelf();
// logs "Hello, my name is Alice", as expected

alice.introduceSelf.call({name: "Bob"});
// logs "Hello, my name is Bob"

alice.introduceSelf.apply({name: "Casey"});
// logs "Hello, my name is Casey"

So .call and .apply allow you to manipulate the this keyword for the invoked function.

On to the main question...

What’s the difference between .call and .apply?

It’s all about the way you pass parameters. That’s it. Let’s make our previous example more complex:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(name){
    this.name = name;
    this.introduceSelf = function(greeting) {
        console.log(greeting + ", my name is " + this.name);
    }
}

var alice = new Person('Alice');
alice.introduceSelf('Hello');
// logs "Hello, my name is Alice", as expected

alice.introduceSelf.call({name: "Bob"}, 'Bonjour');
// logs "Bonjour, my name is Bob"

alice.introduceSelf.apply({name: "Casey"}, ['Hola']);
// logs "Hola, my name is Casey"

For .call you pass the parameters comma separated (like normal). For .apply you pass the parameters in an array.

Why would you even bother having these two ways? Why not standardise?

That’s a fair question. But the two methods have different use cases. If you know exactly how many arguments you're passing, you should use .call. If you don’t know, or if your arguments are already in an array, you should use .apply. (Rephrased from a helpful stackoverflow answer.)

Ok, how am I going to remember this?

Turns out the folks on stackoverflow have some thoughts on that one too. Here’s how I'll be remembering it:

apply uses an array

call counts with commas

Resources


comments powered by Disqus