假设我们有以下代码:
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
是如何做到神奇的……
这就是我认为代码的工作方式,请在错误之处纠正我。
let fn1 = Function.apply.bind(Math.max, null);
创建一个Function.apply(null)
设置为this
的新函数Math.max
并将其分配给fn1
变量。 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
被隐式添加到“全局”方法/对象。现在,让我们重写这两段文字,向您展示魔术的工作原理:)
this
创建一个新函数let fn1 = Function.apply.bind(Math.max, null);
,其中newFunction.apply(null, ...args)
,因此它与函数newFunction == Math.max
相同,并将其分配给Math.max.apply(null, ...args)
变量。 fn1
调用fn1([1, 10, 5]);
魔术透露:)
此问题不是其他问题的重复。有所不同,因为它更具体,在这里我要特别问“为什么调用Function.apply.bind(fn,null)会调用newFunction.apply(null, [1, 10, 5])
,而不是fn.apply
?”而不是“ apply.bind如何工作?”。这就像是在问一个问题:“为什么自行车齿轮会利用踏板的动觉力而不直接通过加速度产生力?”与“自行车如何工作?”这个问题相同
答案 0 :(得分:1)
首先将其分成几部分,bind()
:
bind()方法创建一个新函数,该函数在被调用时将其
this
关键字设置为提供的值,并在给定的参数序列之前添加新的函数被调用。
因此,您正在bind
将apply
方法从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.max
。 null
调用fn1
作为apply
调用Math.max
,并将数组中的条目作为离散参数。