为什么 .bind() 在可选参数前面加上?

Why does .bind() prepend the optional arguments?

我第一次使用 .bind() 时被传递给绑定函数的可选参数放在前面这一事实所困扰。当我试图将事情交给匿名事件处理函数时,这让我明白了,有点像这样:

$('#example').on('change', function(arg1, arg2, evt) {
    console.log(evt, arg1, arg2);
}.bind(null, arg1, arg2));

.bind() 的 MDN 多次提到前置,但从未详细说明,所以我很好奇为什么 - 为什么我必须将 arg1arg2 放在evt 在函数参数中? appending 不是更容易理解并且性能稍微好一点吗?

如果附加绑定参数附加到调用时间参数,行为将如下所示:

function foo(bar, baz) {}
const b = foo.bind(null, 42);

b();          // bar = 42
b('c');       // bar = 'c', baz = 42
b('c', 'd');  // bar = 'c', baz = 'd'

意思是,你的绑定参数将在哪里结束是不可预测的,这可以说是疯狂的。

如果您将 bind 视为 partial application or currying,则前置也更有意义:从功能上讲非常松散,foo.bind(null, 42) returns 部分应用函数,
它变成 a -> b -> c(一个函数有两个值和 returns 第三个)
进入 b -> c(一个只需要一个值和 returns 另一个值的函数)。

bind() 生成一个新函数,该函数在被调用时会调用调用 .bind() 的函数。

让我们命名 f 您在代码中使用的函数:

var g = function f(arg1, arg2, evt) {
    console.log(evt, arg1, arg2);
}.bind(null, arg1, arg2)

bind() 生成一个新函数(存储在 g 中),该函数接受任意数量的参数(本例中为一个)。
g 可以用零个或多个参数调用。

只需要bind()的第一个参数;它是在 bind() 返回的函数中被引用为 this 的对象。 bind() 的其他参数(如果存在)在 g.

中始终可用

在这个例子中它们是 arg1arg2,它们总是传递给 ff 的其他参数是 g 调用时的参数。可能有none,一个或多个

arg1arg2 作为调用 f 和列表其余部分(传递给 [=15= 的参数)的第一个参数是很自然的选择]) 最后。

如果 arg1arg2 作为最后一个参数传递给 f 你必须检查 f 里面的 arguments.length 来找到最后两个参数而且它的代码变得很麻烦。