简体   繁体   English

为什么调用 Function.apply.bind(fn, null) 调用的是 `fn.apply`,而不是 `Function.apply`?

[英]Why call to Function.apply.bind(fn, null) calls `fn.apply`, and not `Function.apply`?

Suppose we have this code:假设我们有这样的代码:

let fn1 = Function.apply.bind(Math.max, null);
fn1([1, 10, 5]); // returns 10

I know that it's a spread function in ES6 we would instead write:我知道它是 ES6 中的一个spread function ,我们会这样写:

Math.max(...[1, 10, 5]);

But I can not understand how Function.apply.bind does its magic...但我无法理解Function.apply.bind如何Function.apply.bind它的魔力......

This is how I think code works, please correct me where I am wrong.这就是我认为代码工作的方式,请纠正我的错误。

  1. This statement let fn1 = Function.apply.bind(Math.max, null);这个语句let fn1 = Function.apply.bind(Math.max, null); creates a new function Function.apply(null) with this set to Math.max and assigns it to fn1 variable.创建一个新的功能Function.apply(null)this设定为Math.max并将其分配给fn1变量。
  2. This statement fn1([1, 10, 5]);这个语句fn1([1, 10, 5]); invokes our newly created function in this manner: Function.apply(null, [1, 10, 5]) with this inside this function set to Math.max .调用我们的新创建的功能以这种方式: Function.apply(null, [1, 10, 5])this将此功能设定为内部Math.max But this call is invalid... if we copy/paste that line in JS console - we will get Uncaught SyntaxError: Unexpected number但是这个调用是无效的……如果我们在 JS 控制台中复制/粘贴那一行 - 我们会得到Uncaught SyntaxError: Unexpected number

So, my question is - how Function.apply knows that it should use this equal to Math.max and "rotate"/modify its call to Math.max.apply ?所以,我的问题是 - Function.apply如何知道它应该使用this等于Math.max并“旋转”/修改它对Math.max.apply调用?

Updated更新

I just understood how all that stuff works!我才明白所有这些东西是如何工作的! First, let's rewrite a code to its "real" form:首先,让我们将代码重写为其“真实”形式:

let fn1 = this.Function.apply.bind(Math.max, null);
this.fn1([1, 10, 5]); // returns 10

Magic?魔法? this is implicitly added to "global" methods/objects. this被隐式添加到“全局”方法/对象。 Now let's rewrite those 2 paragraphs of text to show you how magic works :)现在让我们重写这 2 段文字,向您展示魔法是如何工作的:)

  1. This statement let fn1 = Function.apply.bind(Math.max, null);这个语句let fn1 = Function.apply.bind(Math.max, null); creates a new function newFunction.apply(null, ...args) , where newFunction == Math.max , so it's the same as a function Math.max.apply(null, ...args) and assigns it to fn1 variable.创建一个新函数newFunction.apply(null, ...args) ,其中newFunction == Math.max ,因此它与函数Math.max.apply(null, ...args)并将其分配给fn1变量.
  2. This statement fn1([1, 10, 5]);这个语句fn1([1, 10, 5]); calls newFunction.apply(null, [1, 10, 5])调用newFunction.apply(null, [1, 10, 5])

Magic revealed :)魔法揭晓:)

Duplicate update重复更新

This question is not a duplicate of another question.这个问题不是另一个问题的重复。 It's different because it's more concrete, here I am asking specifically "Why call to Function.apply.bind(fn, null) calls fn.apply , and not Function.apply ?"它不同,因为它更具体,在这里我特别问“为什么调用 Function.apply.bind(fn, null) 调用fn.apply ,而不是Function.apply ?” and not "How apply.bind works?".而不是“apply.bind 是如何工作的?”。 It's like saying that a question "Why bicycle gears use kinesthetic force of pedals and not directly generate force by acceleration?"这就像在问“为什么自行车齿轮使用踏板的动觉力而不是通过加速直接产生力”的问题? is the same as a question "How does a bicycle work?"与“自行车如何工作?”的问题相同。

Let's split it into parts, first of all, bind() :让我们把它分成几部分,首先是bind()

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. bind()方法创建一个新函数,当调用this函数时,将其this关键字设置为提供的值,在调用新函数时,在任何提供的参数之前都有给定的参数序列。

So you are bind ing the apply method from Function global object to Math.max .因此,您bind Function全局对象中的apply方法bindMath.max

The function fn1 returned by bind() is therefore equivalent to this.apply() , where this really is Math.max , exactly as you "asked" to the bind() method.因此, bind()返回的函数fn1等效于this.apply() ,其中this实际上是Math.max ,正如您对bind()方法“询问”的那样。

This line:这一行:

let fn1 = Function.apply.bind(Math.max, null);

...is really tricky. ……真的很麻烦。 :-) It calls bind on Function.apply , creating a function that will call apply with Math.max as the this value and null as the first argument (the thisArg that apply should use when calling Math.max ; Math.max doesn't care about this , so null is fine). :-)它要求bindFunction.apply ,创建将调用一个函数applyMath.maxthis值和null作为第一个参数(thisArg apply打电话时应该使用Math.max ; Math.max没有按”不关心this ,所以null很好)。

When you call fn1 , it calls Function.apply with this set to Math.max , and null as the first argument, followed by the array you pass into fn1 .当您调用fn1 ,它会调用Function.apply并将this设置为Math.max ,并将null作为第一个参数,然后是您传递给fn1的数组。 apply calls Math.max with null as this and the entries from the array as discrete arguments. apply使用null作为this调用Math.max ,并将数组中的条目作为离散参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM