【发布时间】:2014-05-30 05:29:54
【问题描述】:
假设,为了这个问题,我希望能够在 Javascript 中创建一个函数,将一个数组的所有元素附加到另一个数组。如果您可以访问目标数组,那么实现此目的的一种方法是:
var destination = [1,2,3];
var source = [4,5];
Array.prototype.push.apply(destination, source);
console.log(destination); // [1,2,3,4,5]
现在,由于 Array.prototype.push.apply 非常丑陋,我想给它取一个更好的别名,比如:
var pushAll = Array.prototype.push.apply;
我应该能够使用两个参数调用,上下文(目标)和参数数组(源)。但是,当我尝试使用别名时,会发生这种情况:
pushAll(destination, [6,7]);
TypeError: Function.prototype.apply was called on [object global], which
is a object and not a function
很明显apply 函数没有绑定到push,这导致我尝试这个:
var pushAll = Function.prototype.apply.bind(Array.prototype.push);
pushAll(destination, [6,7]);
console.log(destination); // [1,2,3,4,5,6,7,8]
这显然工作正常。我的问题是,为什么我必须绑定push方法才能应用? Array.prototype.push.apply 不应该已经绑定应用了吗?为什么以不同的名称调用它会导致在未绑定的上下文中调用它?
【问题讨论】:
-
反之亦然:您必须将
apply方法绑定到数组push函数! -
@Bergi 我很好奇你的意思。我是 JavaScript 和绑定函数概念的新手。当我说
Function.prototype.apply.bind(Array.prototype.push)时,我是将push绑定到apply的this值,还是将apply绑定到push? -
但答案很简单,没有隐式绑定。方法在实例之间共享,并且您正在传递对该方法的引用。如果它被绑定,它就不能用作通用方法。而且它无法即时做出决定,因为它不知道它的最终意图是什么。
-
是的,确实如此,here 对此略有改进。小提琴还包括你想要的东西,即有一个指向
push方法的函数(如var _oldPush = Array.prototype.push),这样你就可以使用call和apply就可以了(@987654341 @)?
标签: javascript prototype bind apply