dewd
dewd

Reputation: 4429

Need for JavaScript call method on function object

Take a simple anonymous function which accepts 3 parameters:

function hello(firstname, surname, city) {
    console.log('Hi ' + firstname + ' ' +
                        surname + '. I see you\'re from ' + city)
}

What is the benefit of calling this function using the function method "call" over say just calling the function?, ie.

hello('Jane','Mansfield','Philadelphia');

vs

hello.call(this,'Jane','Mansfield','Philadelphia');

Fiddle-dee-dee: http://jsfiddle.net/wC3xz/1/

Sorry, but looking at the docs hasn't shed any light. The only thing I can think of is if you can gain access to the this object passed to the function. But wouldn't accessing this from within the anonymous function be this in the context of the anonymous function ie the window?

When is call needed instead of just functionname(args)?

Upvotes: 3

Views: 157

Answers (4)

dr.eval
dr.eval

Reputation: 116

So what's the big deal about call?

Call is defined in the spec in section 15.3.4.4. You use .call when you are trying to set the thisArg inside the function.

How would Ito use it?

Here is an example of how you would use it:

var me = { name: 'dr.eval' }

foo.call(me); // if you omitted the 'call' it would error because this defaults to the window object.

function foo() {
    alert(this.name + ' is home');
}

you can read more about it here: Function.prototype.call

When would I use it?

Here is a very canonical example when using call:

A lot of DOM methods return NodeList. While NodeList is an array-like object, you cannot natively call array methods on them. However, since they are, by design, like arrays, you can use array methods on them using .call

If you open the console and type

document.getElementsByTagName("a").forEach

You'd get undefined, because it returns a NodeList, which does not have a forEach method. However, iterating a NodeList might be desirable, so you can do the following:

[].forEach.call(document.getElementsByTagName("a"),function(elem){
     console.log(elem);
});

Which would log all the anchor elements on the page.

Another common example is arguments which is another "Array Like" object. Often, we want to process arguments like an array but we can't. So again, .call comes to the rescue and we can do:

[].slice.call(arguments,0); // returns a clone of arguments, but a real array we can work with!

It's also useful when working with events, and in general it shows how flexible JavaScript is. It's a way to share functionality between objects that otherwise would not have been able to share it.

Upvotes: 10

Jan Turoň
Jan Turoň

Reputation: 32912

What is the benefit of calling this function using the function method "call" over say just calling the function?

  • None. It is useful only if you want to transfer context (this) to the function

When is call needed instead of just functionname(args)?

  • when you want to call existing method in different context than it is defined. For example, arguments object is similar to Array, but you can not use sort() directly.

    function Test() {
      // call sort from Array context onto arguments object
      console.log(Array.prototype.sort.call(arguments)); // 2 3 5 8
      // error: arguments object doesn't contain sort
      console.log(arguments.sort());
    }
    Test(5,3,8,2);
    

Upvotes: 2

Jonast92
Jonast92

Reputation: 4967

You use

.call

and

.apply

when it comes to overriding.

this is a good article to learn more.

Upvotes: 1

Stephen Thomas
Stephen Thomas

Reputation: 14053

The benefit of using call() in general is that it allows you to set the context for the function explicitly. There's not much value in that for a simple function as you show, but if your function is a method of an object or if it's a callback, setting the context can be relevant.

Upvotes: 0

Related Questions