为什么apply尚未绑定到Javascript中的函数? [英] Why is apply not already bound to functions in Javascript?

查看:87
本文介绍了为什么apply尚未绑定到Javascript中的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了这个问题,假设我希望能够用Javascript创建一个将一个数组的所有元素附加到另一个数组的函数.如果可以访问目标数组,则可以实现此目的的一种方法是说:

Assume, for the sake of this question, that I want to be able to create a function in Javascript that appends all of the elements of one array to another array. One way to achieve this, if you have access to the destination array, is to say:

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非常丑陋,我想将其别名为更好的名称,例如:

Now, since Array.prototype.push.apply is pretty ugly, I want to alias it to something nicer, like:

var pushAll = Array.prototype.push.apply;

我应该能够用两个参数来调用,即上下文(目标)和参数数组(源).但是,当我尝试使用别名时,会发生这种情况:

Which I should be able to call with two arguments, the context (destination) and an array of arguments (source). However, when I try to use the alias, this happens:

pushAll(destination, [6,7]);
TypeError: Function.prototype.apply was called on [object global], which
is a object and not a function

因此很明显apply函数未绑定到push,这促使我尝试了此操作:

So clearly the apply function is not bound to push, which led me to try this:

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应该已经绑定了吗?为什么以不同的名称调用它会导致在未绑定的上下文中调用它?

Which clearly works fine. My question is, why do I have to bind the push method to apply? Shouldn't Array.prototype.push.apply already be bound to apply? Why does calling it under a different name result in calling it on an unbound context?

推荐答案

为什么必须绑定push方法才能应用?

why do I have to bind the push method to apply?

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

It's the other way round: You have to bind the apply method to the Array push function - you can bind it to other functions as well! Otherwise apply doesn't know which method to apply with the arguments.

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

Function.prototype.apply.bind(Array.prototype.push); does call the bind function on the apply function with push as the argument, the argument on which apply is then bound. The resulting function pushAll will, when called, invoke apply on the push function, and pass it's argument (the array and the arguments array) to it.

Array.prototype.push.apply是否一定要应用?

Shouldn't Array.prototype.push.apply already be bound to apply?

不. JavaScript旨在在调用函数时绑定上下文,而在将其称为属性时尚未绑定-对属性的访问没有隐式绑定.否则,在您可以在其上调用诸如bind/apply之类的任何Function方法并尝试在其他上下文中使用它之前,Array.prototype.push已经绑定至Array.prototype.

Nope. JavaScript is designed to bind the context at the call of a function, not already when it's being referred to as a property - there is no implicit binding on property access. Otherwise Array.prototype.push would already be bound to Array.prototype, before you could call any Function methods like bind/apply on it and try to use it with a different context.

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

Why does calling it under a different name result in calling it on an unbound context?

名字没什么大不一样,但是样式却不一样. (未绑定)当在函数上将它们作为方法调用时,即当对被调用函数的引用是属性访问时,函数确实将其this值设置为对象.destination.push().

It's not so much different name, but different style. (Unbound) Functions do get their this value set to the object when they are called as a method on it, i.e. when the reference to the called function is a property access: destination.push().

这提供了极大的灵活性,您可以从一个对象借用"功能并在其他对象上调用它们,而这些功能仍然是相同的(未绑定)功能.在功能对象不是一流对象的语言中,这几乎是不可能的.

This allows for great flexibility, you can "borrow" functions from an object and call them on other objects, still being the same (unbound) function. This is rather impossible in languages where function objects are no first-class objects.

如果将函数(即使它们原本是方法)称为普通函数(pushAll()),则它们的this值将为undefined(除非在草率模式下).在 this关键字上了解更多信息. MDN.

If functions (even though they were meant to be methods) are called as plain functions (pushAll()), their this value will be undefined (unless in sloppy mode). Read more on the this keyword at MDN.

这篇关于为什么apply尚未绑定到Javascript中的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆