Javascript 为什么在curry函数的这个实现中需要使用bind

Javascript 为什么在curry函数的这个实现中需要使用bind,javascript,currying,Javascript,Currying,有一个来自的咖喱功能 为什么在(*)行中需要使用绑定?它可以被替换为 return curry(fn, arity, ...args) // line(**) ?使用函数#bind只有两个原因: 当您想要将函数绑定到特定的上下文对象时。实际上,当您希望提前确保函数中的this关键字将引用特定的已知对象时 当您想要预先定义一些参数时,a.k.a.“部分函数应用程序” 第二种情况很好地说明了函数currying的意义——使N元函数可以灵活调用,如: fn(arg1,arg2,…,argN),或

有一个来自的咖喱功能

为什么在(*)行中需要使用绑定?它可以被替换为

return curry(fn, arity, ...args) // line(**)

使用
函数#bind
只有两个原因:

  • 当您想要将函数绑定到特定的上下文对象时。实际上,当您希望提前确保函数中的
    this
    关键字将引用特定的已知对象时
  • 当您想要预先定义一些参数时,a.k.a.“部分函数应用程序”
  • 第二种情况很好地说明了函数currying的意义——使N元函数可以灵活调用,如:

    • fn(arg1,arg2,…,argN)
      ,或
    • fn(arg1,arg2,…)(argN)
      ,或
    • fn(arg1,arg2)(…,argN)
      ,或
    • fn(arg1)(arg2)(…)(argN)
    这里需要注意的重要一点是,除了第一种情况外,所有情况下都需要多个单独的函数。假设您有一个接受3个参数的辅助函数。你可以

  • …为辅助函数传递足够的参数,即3个或更多。然后
    curry()
    使用这3个参数调用worker函数并返回结果。
    这使得
    fn(arg1、arg2、arg3)
    成为可能
  • …为辅助函数传递的参数太少。然后
    curry()
    不调用辅助函数,但必须返回一个新函数,该函数接受剩余数量的参数。
    这使得所有
    fn(arg1)(arg2,arg3)
    fn(arg1,arg2)(arg3)
    fn(arg1)(arg2)(arg3)
    成为可能
  • Function#bind
    介绍了第二种情况:它为辅助函数创建一个新的包装函数,并用给定的值预先填充辅助函数的一些参数槽。上下文对象与该意图无关,因此在这里使用
    null
    就可以了

    const curry = (fn, arity = fn.length, ...args) =>
        //  enough arguments ?    call     :   remember arguments so far & defer 
        args.length >= arity ? fn(...args) : curry.bind(null, fn, arity, ...args);
    
    所以要回答这个问题:不,您不能使用
    返回curry(fn,arity,…args)
    ,因为这不做最重要的事情,也就是创建一个新函数


    示例:假设我们有一个worker函数,它搜索字符串并返回命中数

    const search = (str, substr) => {
        var hits = 0, pos = 0;
        while (true) {
            pos = str.indexOf(substr, pos) + 1;
            if (pos) hits++; else return hits;
        }
    }
    
    现在,我们可以创建一个可以记住目标字符串的咖喱版本,只需切换最后一个参数:

    const flexibleSearch = curry(search);
    
    const reusableSearch = flexibleSearch("... a ... b ... c ... a ... b ... a");
    
    reusableSearch("a")   // -> 3
    reusableSearch("b")   // -> 2
    reusableSearch("c")   // -> 1
    reusableSearch("d")   // -> 0 
    
    @托马拉克是对的

    假设您有一个函数,它接受100个参数
    fn(1,2,3,…100){}

    fn.bind(null,99100)
    使用预设前导参数创建一个新函数。在我们的示例中,将使用参数1,2,…97,98的默认值,并期望有两个参数作为新函数的输入,该函数将用作参数99和100

    在本例中,我们使用函数来接受部分参数

    你可以通过这些来获得更深入的理解 和

    fn.bind()
    始终返回新函数。而
    fn()
    将调用该函数。“它可以替换为
    返回咖喱(fn,arity,…args)
    ”您可以替换为
    返回(…args2)=>咖喱(fn,arity,…args,…args2)
    您的答案非常详细和彻底。我对你的答案投了赞成票,因为它非常详细和准确。我仍然在添加一个答案来简化事情。
    const flexibleSearch = curry(search);
    
    const reusableSearch = flexibleSearch("... a ... b ... c ... a ... b ... a");
    
    reusableSearch("a")   // -> 3
    reusableSearch("b")   // -> 2
    reusableSearch("c")   // -> 1
    reusableSearch("d")   // -> 0