在JavaScript中使用Function.call.apply的目的是什么?

时间:2011-09-18 05:57:57

标签: javascript

当我偶然发现用于创建“快速,未绑定的包装器”的Function.call.apply hack时,我正在浏览JavaScript Garden。它说:

  

另一个技巧是同时使用call和apply来创建快速,未绑定的包装器。

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

我不明白的是,当Function.apply足够时,为什么还要使用Function.call.apply。毕竟,它们在语义上都是等价的。

2 个答案:

答案 0 :(得分:14)

不,Function.call.applyFunction.apply在这种情况下不一样。

假设原始调用者调用

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

通过调用和一起应用,就像在JavaScript Garden代码中一样。执行

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

(松散地,在数组表示法中写arguments):

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

使用Function.call调用this==Foo.prototype.method

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

调用Foo.prototype.methodthis设置为t,参数xyz。甜。就像在评论中一样。我们已成功制作了包装纸。

现在假设你左边只说Function.apply而不是Function.call.apply,你声称它在语义上是等价的。你会有

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

(松散地)

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

调用函数Function(唉!),其中this设置为Foo.prototype.method,参数txyz

完全不一样。

答案 1 :(得分:4)

这意味着您可以使用另一个对象中的方法。

一个很好的例子是所有函数都有的参数变量,它就像一个数组但不是一个数组,所以你可以在它上面调用数组的方法:

Array.prototype.join.call(arguments, ",");