开发者

What's the purpose of using Function.call.apply in 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 cal开发者_运维技巧l 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.


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.


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, ",");
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜