【问题标题】:Why does .bind() prepend the optional arguments?为什么 .bind() 前置可选参数?
【发布时间】:2018-03-20 13:09:41
【问题描述】:

当我第一次使用 .bind() 时,我被传递给绑定函数的可选参数是预先添加的这一事实绊倒了。当我试图将事情交给匿名事件处理函数时,这让我受益匪浅,有点像这样:

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

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

【问题讨论】:

  • 这些参数的“可选”是什么?就Javascript而言,什么都没有。通过从左侧绑定参数,您可以确定将按什么顺序处理它们,而您完全不知道绑定参数最终会是什么参数,就好像它们将附加到调用时传递的参数的末尾一样时间。
  • 是的,追加会更容易。这正是这里发生的事情。传递的参数附加到之前绑定的参数
  • 在这种情况下,附加的是 evt 参数。
  • @deceze 它们是“可选的”,因为它们不是必需的 - 除了“thisArg”之外,我没有给 bind() 任何东西。
  • 啊,我明白了,additional arguments 传递给了 bind 方法。

标签: javascript ecmascript-5


【解决方案1】:

如果附加绑定参数附加到调用时参数,行为将是这样的:

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 applicationcurrying,前置也更有意义:从功能上讲,foo.bind(null, 42) 返回一个部分应用函数,
它变成了a -> b -> c(一个接受两个值并返回第三个值的函数)
进入b -> c(一个只接受一个值并返回另一个值的函数)。

【讨论】:

  • 非常有趣 - 这很有意义。谢谢!
【解决方案2】:

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 被调用时的参数。可能没有,一个或多个。

很自然地选择将arg1arg2 作为调用f 的第一个参数,并将列表的其余部分(传递给g 的参数)放在最后。

如果arg1arg2 作为最后一个参数传递给f,则必须检查f 内的arguments.length 才能找到最后两个参数,并且其代码变得很麻烦。

【讨论】:

    猜你喜欢
    • 2013-11-19
    • 2020-10-23
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多