Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of using Function.call.apply in JavaScript?

Tags:

javascript

I was browsing through the JavaScript Garden when I stumbled upon the Function.call.apply hack which is used to create "fast, unbound wrappers". It says:

Another trick is to use both call and apply together to create fast, unbound wrappers.

function Foo() {}

Foo.prototype.method = function(a, b, c) {
    console.log(this, a, b, c);
};

// Create an unbound version of "method" 
// It takes the parameters: this, arg1, arg2...argN
Foo.method = function() {

    // Result: Foo.prototype.method.call(this, arg1, arg2... argN)
    Function.call.apply(Foo.prototype.method, arguments);
};

What I don't understand is why bother using Function.call.apply when Function.apply would suffice. After all, both of them are semantically equivalent.

like image 457
Aadit M Shah Avatar asked Sep 18 '11 05:09

Aadit M Shah


People also ask

What is function call and apply in JavaScript?

The Difference Between call() and apply() The difference is: The call() method takes arguments separately. The apply() method takes arguments as an array. The apply() method is very handy if you want to use an array instead of an argument list.

What is the purpose of calling a function?

A function is a set of code that performs a specific task and can be used whenever needed just by calling it. While using multiple function calls or recursion, the concept of a function call is very necessary to be known, for better understanding of the code.

Why we use call () apply and bind in JavaScript?

Call invokes the function and allows you to pass in arguments one by one. Apply invokes the function and allows you to pass in arguments as an array. Bind returns a new function, allowing you to pass in a this array and any number of arguments.

Why do we need call method in JavaScript?

The call() method is a predefined JavaScript method. It can be used to invoke (call) a method with an owner object as an argument (parameter). With call() , an object can use a method belonging to another object.


2 Answers

No, Function.call.apply and Function.apply are not the same in this case.

Let's say the original caller invokes

Foo.method(t, x, y, z)

With call and apply together, as in the JavaScript Garden code. This executes

Function.call.apply(Foo.prototype.method, arguments);

which is (loosely, writing arguments in array-notation):

Function.call.apply(Foo.prototype.method, [t, x, y, z]);

which invokes Function.call with this==Foo.prototype.method:

Foo.prototype.method.call(t, x, y, z)

which calls Foo.prototype.method with this set to t and arguments x, y, and z. Sweet. Just like in the comments. We have successfully made a wrapper.

Now suppose you left said just Function.apply instead of Function.call.apply, which you claim is semantically equivalent. You would have

Function.apply(Foo.prototype.method, arguments);

which is (loosely)

Function.apply(Foo.prototype.method, [t, x, y, z]);

which calls the function Function (ugh!) with this set to Foo.prototype.method and arguments t, x, y, and z.

Not the same at all.

like image 67
Ray Toal Avatar answered Sep 22 '22 18:09

Ray Toal


It means you can use the methods from an object on another one.

A good example is the arguments variable all functions have, it's like an array but not an array so you can call array's methods on it thus:

Array.prototype.join.call(arguments, ",");
like image 22
Tom Avatar answered Sep 20 '22 18:09

Tom