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

什么';在JavaScript中使用Function.call.apply的目的是什么?,javascript,Javascript,我在浏览时偶然发现了Function.call.apply hack,它用于创建“快速、未绑定的包装”。它说: 另一个技巧是同时使用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 para

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

另一个技巧是同时使用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。毕竟,它们在语义上是等价的。

这意味着您可以在另一个对象上使用来自一个对象的方法

一个很好的例子是所有函数都具有的参数变量,它类似于数组,但不是数组,因此可以对其调用数组的方法,因此:

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

否,
Function.call.apply和
Function.apply在本例中不相同

假设原始调用方调用

Foo.method(t, x, y, z)
与调用和应用一起使用,如JavaScript Garden代码中所示。执行

Function.call.apply(Foo.prototype.method, arguments);
这是(粗略地说,用数组表示法编写
参数
):

调用
函数。调用
时使用
this==Foo.prototype.method

Foo.prototype.method.call(t, x, y, z)
它调用
Foo.prototype.method
,将
this
设置为
t
,参数
x
y
z
。好极了。就像在评论中一样。我们已经成功地做了一个包装

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

Function.apply(Foo.prototype.method, arguments);
这是(松散的)

它调用函数
function
(ugh!),将
this
设置为
Foo.prototype.method
和参数
t
x
y
z


一点也不一样。

我确实发了一个链接到。如果你想直接跳转到包含文章的部分,然后点击.tnx,-这似乎意味着这个黑客可以提高一些速度。。但是,实际上,不要使用它。@Aadit
Function.call.apply
Function.apply
在这里不能相同,因为前者应用
Function.call
,而后者尝试应用
Function
构造函数。细节在我的回答中,但我敢打赌,如果伊沃·韦策尔来回答这个问题,他的回答将更加雄辩和易懂。这是相当深刻的东西。我同意这可能不是你应该使用的东西,除非你想让同事花半个小时来理解它我认为
函数.call
实际上有点误导。它实际上应该是
Function.prototype.call
,因为
Function.call
可能会被覆盖<代码>函数
毕竟只是一个函数对象。(是的,这很难理解)@Pubbaa80尽管
Function.call===Function.prototype.call
在没有令人讨厌的事情的情况下,我完全同意你的看法。但是请注意
JSON.stringify(Object.getOwnPropertyDescriptor(Function.prototype,“call”)
返回
{“writable”:true,“enumerable”:false,“configurable”:true}
,因此真正的邪恶也可以覆盖
Function.prototype.call。是的。但是
apply
位在原始问题中做了什么?@CameronSkinner:function对象的
apply
方法执行该函数,在该执行中将第一个参数视为
this
,将第二个参数视为
arguments
fn.apply(a[b,c])
相当于
fn.call(a,b,c)
。但是这种包装的目的是什么?目的是调用
Foo.prototype.method
,而不将其绑定到
Foo
的实例。而是在
Foo.prototype.method
中传递自己的值作为
this
的值。你为什么要这样做?也许你想要做一些函数编程,而你想要映射、减少或过滤的函数恰好是一个绑定方法。如果你不想把它绑定到一个对象,你可以调用一个“未绑定的包装器”。这是一个奇怪的术语,因为你最终要把这个方法绑定到你自己的对象上(但你可以忽略它…)好吧,据我所知,下面的语句是等价的:Function.call.apply(Foo.prototype.method,arguments);Foo.prototype.method.apply(参数[0],Array.prototype.slice.call(参数,1));它们都可以用来创建未绑定的包装。然而,第一种方法更短、更快、更直观。令人惊叹的!
Function.apply(Foo.prototype.method, arguments);
Function.apply(Foo.prototype.method, [t, x, y, z]);