Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

clarification on the purpose of `Function.call.apply` #143

Closed
twobitfool opened this Issue · 4 comments

3 participants

@twobitfool

In the function arguments section, there is a mention of using call and apply together...

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);
};

However, it is unclear what Function.call.apply is doing. It might be worth showing the longer equivalent, which I believe is ...

Foo.method = function() {
  var args = Array.prototype.slice.apply(arguments)
  var obj = args.shift()
  Foo.prototype.method.apply(obj, args)
};
@timruffles
Collaborator

Yeah I'm not sure about this one either, will research and update the text. If it's a performance thing, it needs a better explanation!

@jozsefDevs

Okay, so here is an explanation of the mentioned problem:

Actually, we want to call a function within a context, with an array-like arguments object.

Function.call is a handy tool to call a function within a context, but it can't handle array-like objects as it arguments.
(The Function.call part is like Array.prototype.slice, we'd like to call a function that won't be overdefined by anyone)

So we want to call Function.call.apply what would do the job. Call "Function.call" within a context as it first argument, with an array-like object as it second.

So to fully understand this line:

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

You would better put parenthesis while you read like:

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

It has nothing to do with performance I think. The Function.call part will return a function that you can call with apply. That's all.

@twobitfool

Thanks for the followup. Makes sense.

On the first read, I was a little confused by the "trick" of calling apply on Function.call, and wondered if it would be better to be more explicit (and verbose). But I see the value in the one-liner, and (with the comments) it's a nice trick.

BTW, Happy New Year!

@jozsefDevs

Happy New Year as well!

@timruffles timruffles closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.