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

时间:2018-09-22 18:01:10

标签: javascript bind apply

假设我们有以下代码:

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

我知道它是ES6中的spread function,我们改为:

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

但是我不明白Function.apply.bind是如何做到神奇的……

这就是我认为代码的工作方式,请在错误之处纠正我。

  1. 此语句let fn1 = Function.apply.bind(Math.max, null);创建一个Function.apply(null)设置为this的新函数Math.max并将其分配给fn1变量。
  2. 此语句fn1([1, 10, 5]);以这种方式调用我们新创建的函数:Function.apply(null, [1, 10, 5]),其中函数内部的this设置为Math.max。但是此调用无效...如果我们在JS控制台中复制/粘贴该行-我们将得到Uncaught SyntaxError: Unexpected number

所以,我的问题是-Function.apply如何知道它应该使用等于this的{​​{1}}并“旋转” /修改对Math.max的调用?

已更新

我只是了解所有这些东西是如何工作的!首先,让我们将代码重写为“真实”形式:

Math.max.apply

魔术? let fn1 = this.Function.apply.bind(Math.max, null); this.fn1([1, 10, 5]); // returns 10 被隐式添加到“全局”方法/对象。现在,让我们重写这两段文字,向您展示魔术的工作原理:)

  1. 此语句this创建一个新函数let fn1 = Function.apply.bind(Math.max, null);,其中newFunction.apply(null, ...args),因此它与函数newFunction == Math.max相同,并将其分配给Math.max.apply(null, ...args)变量。
  2. 此语句fn1调用fn1([1, 10, 5]);

魔术透露:)

重复更新

此问题不是其他问题的重复。有所不同,因为它更具体,在这里我要特别问“为什么调用Function.apply.bind(fn,null)会调用newFunction.apply(null, [1, 10, 5]),而不是fn.apply?”而不是“ apply.bind如何工作?”。这就像是在问一个问题:“为什么自行车齿轮会利用踏板的动觉力而不直接通过加速度产生力?”与“自行车如何工作?”这个问题相同

2 个答案:

答案 0 :(得分:1)

首先将其分成几部分,bind()

  

bind()方法创建一个新函数,该函数在被调用时将其this关键字设置为提供的值,并在给定的参数序列之前添加新的函数被调用。

因此,您正在bindapply方法从Function全局对象转移到Math.max

因此,fn1返回的函数bind()等效于this.apply(),其中this的确是Math.max,与您向{ {1}}方法。

答案 1 :(得分:0)

此行:

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

...真的很棘手。 :-)它在bind上调用Function.apply,创建一个函数,该函数将以apply作为Math.max的值和this作为{第一个参数(调用null时应使用apply thisArg Math.max并不关心Math.max,所以this很好)。

调用null时,它将调用fn1设置为Function.apply的{​​{1}},并且将this作为第一个参数,然后传递数组进入Math.maxnull调用fn1作为apply调用Math.max,并将数组中的条目作为离散参数。