【问题标题】:Why is apply not already bound to functions in Javascript?为什么 apply 尚未绑定到 Javascript 中的函数?
【发布时间】: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 绑定到applythis 值,还是将apply 绑定到push
  • 但答案很简单,没有隐式绑定。方法在实例之间共享,并且您正在传递对该方法的引用。如果它被绑定,它就不能用作通用方法。而且它无法即时做出决定,因为它不知道它的最终意图是什么。
  • 是的,确实如此,here 对此略有改进。小提琴还包括你想要的东西,即有一个指向push方法的函数(如var _oldPush = Array.prototype.push),这样你就可以使用callapply就可以了(@987654341 @)?

标签: javascript prototype bind apply


【解决方案1】:

为什么一定要绑定push方法才能申请?

反之亦然:您必须将 apply 方法绑定到 Array push 函数 - 您也可以将其绑定到其他函数!否则apply 不知道哪个方法与参数一起应用。

Function.prototype.apply.bind(Array.prototype.push); 确实调用了bind 函数onpush 作为参数的apply 函数,然后是apply 的参数on边界。生成的函数 pushAll 将在调用时调用 apply on push 函数,并将其参数(数组和参数数组)传递给它。

Array.prototype.push.apply 不应该已经绑定应用了吗?

不。 JavaScript 旨在在函数调用时绑定上下文,而不是在它被称为属性时绑定 - 属性访问没有隐式绑定。否则,Array.prototype.push 将已经绑定到 Array.prototype,在您可以调用任何 Function 方法(如绑定/应用)并尝试在不同的上下文中使用它之前。

为什么以不同的名称调用它会导致在未绑定的上下文中调用它?

这不是名字不同,而是风格不同。 (未绑定)函数确实将它们的this 值设置为对象,当它们被调用时作为方法,即当对被调用函数的引用是属性访问时:destination.push()

这提供了极大的灵活性,您可以从一个对象“借用”函数并在其他对象上调用它们,仍然是相同的(未绑定的)函数。这在函数对象不是一等对象的语言中是相当不可能的。

如果函数(即使它们本来是方法)被称为普通函数(pushAll()),它们的this 值将是undefined(除非在草率模式下)。在 MDN 上阅读更多关于 this keyword 的信息。

【讨论】:

  • 如果您想了解更多代码示例,请提及 :-)
  • 您也可以类似地使用call,例如:['one ',' liner'].map(Function.prototype.call.bind(String.prototype.trim));
猜你喜欢
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2012-04-02
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多