When should I use call() vs invoking the function directly?
Asked Answered
A

6

16

I've got a JavaScript application that uses a lot of callbacks. A typical function will take a callback, and wrap it with another callback.

Namespace.foo = function( arg, their_on_success ) {
    var my_on_success = function( result ) {
        console.log( 'my_on_success() called' );
        if( 'function' === typeof their_on_success ) {
              their_on_success( result );
        }
    }
    something( arg, my_on_success );
};

Given the above example, when should such a setup us the native call() method (passing the result var as the second argument) rather than invoking their_on_success() and passing in the result via function invocation?

Adultery answered 19/10, 2011 at 17:46 Comment(0)
M
21

call() is used to change the this value of the function:

var obj = {a: 0};
method.call(obj, "parameter");
function method(para) {
    this.a == 0; // true <-- obj is now this
}
Matthaus answered 19/10, 2011 at 17:49 Comment(0)
P
9

The only reason to use call (or apply) is if you want to set the value of this inside the function.

Well, I guess apply can be useful in other cases as it accepts an array of parameters.

Parallelepiped answered 19/10, 2011 at 17:49 Comment(1)
The main case for apply is when dealing with variable arguments, so you can just pass arguments to it.Erinerina
A
4

Using a function's call() method allows you to changed the object that's bound to the function as this during the execution of the function - this is also called the context

their_on_success.call(myContext, results)

But, if your callback function does not depend on this, it make no difference which way you call it.

Asch answered 19/10, 2011 at 17:52 Comment(0)
E
3

A good example is when implementing a function that needs a callback. When writing OO code, you want to allow the caller to specify the context that a callback will be called.

function validateFormAjax(form, callback, context) {
  // Using jQuery for simplicity
  $.ajax({
    url: '/validateForm.php',
    data: getFormData(form),
    success: function(data) {
      callback.call(context, data);
    }
  });
}

Note that my example could just be implemented by passing the context parameter to the $.ajax call, but that wouldn't show you much about using call

Erinerina answered 19/10, 2011 at 19:31 Comment(0)
W
1

Another case for using call() is when you are in an environment where you can't trust the object's own method hasn't been replaced or you know it doesn't actually have the method you want to run on it. hasOwnProperty is often such a method - there are many places where javascript objects may not have their own hasOwnProperty method so invoking it as hasOwnProperty.call(obj, propertyName) is prudent.

Wittol answered 9/2, 2017 at 3:46 Comment(1)
I get what you're saying but I think it can be improved. Something like: JavaScript lets you specify no prototype at all (Object.create(null)) , override properties on the prototypes of native objects, or even on the object itself. Therefore, to be safe, one should use Object.prototype.hasOwnProperty.call(obj, 'someProp') for your code to be bullet proof.Erinerina
S
0

One scenario I often use "call" is splice arguments:

const fn = function() {
    const args = Array.prototype.slice.call(arguments, 0);
    console.log(args);
}

Notice that arguments is an object. the args however is an array.

Sliwa answered 27/8, 2018 at 23:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.