绑定与咖喱的Javascript用法?

Roy*_*mir 24 javascript currying

我想了解curryvs 之间的区别bind.

执行bind是:

/*1*/   Function.prototype.bind = function ()
/*2*/   {
/*3*/        var fn = this,
/*4*/           args = Array.prototype.slice.call(arguments);
/*5*/       var object = args.shift();
/*6*/       return function ()
/*7*/       {
/*8*/           return fn.apply(object, 
/*9*/                           args.concat(Array.prototype.slice.call(arguments)))
/*10*/       };
/*11*/   }
Run Code Online (Sandbox Code Playgroud)

执行curry是:

/*1*/   Function.prototype.curry = function ()
/*2*/   {
/*3*/       var fn = this,
/*4*/           args = Array.prototype.slice.call(arguments);
/*5*/       return function ()
/*6*/       {
/*7*/           return fn.apply(this, 
/*8*/                           args.concat(Array.prototype.slice.call(arguments)));
/*9*/       };
/*10*/   };
Run Code Online (Sandbox Code Playgroud)

我已经知道这curry不是一个内部函数(不像bindIE9 +中那样).但仍然:

为什么我听到人们一直在谈论curry ,虽然他们可以简单地使用bind操作?

唯一的区别是实际上只在bind 函数中找到的上下文.

分歧

在此输入图像描述

示例:

假设我有这个功能:

function add(x,y,z)
{
  return x+y+z;
}
Run Code Online (Sandbox Code Playgroud)

我可以这样做curry:

alert(add.curry(2).curry(1)(4)) //7
Run Code Online (Sandbox Code Playgroud)

但我也可以这样做:

alert(add.bind(undefined,2).bind(undefined,1)(4)) //7
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这个curry术语函数存在,同时可以向绑定函数添加一个虚拟上下文.

我错过了什么?

Jam*_*mes 22

意图有所不同.

Currying是为了减少参数的数量,通常是为了避免使用相同的初始参数调用函数.例如:

var celsiusToKelvin = add.curry(273.15);
Run Code Online (Sandbox Code Playgroud)

bind()用于确保将函数附加到对象.它也恰好提供了一个currying工具,所以是的你可以使用bind()来curry(),但是如果你想要咖喱,curry()的参数更少,并显示你的意图.


Ami*_*sef 21

bind强制您将上下文附加到函数,而通过使用curry,您可以延迟函数上下文的规范,直到调用 curried函数,在许多情况下很有用.
考虑下面的例子(不完美的,只是为了说明这个想法):

function Query(sessionKey, dataBuilder) {
  this.sessionKey = sessionKey;
  this.url = "http://www.example.com/search";
  this.dataBuilder = dataBuilder
  this.search = function (term) {
    $.ajax({
      type: "POST",
      url: this.url,
      data: this.dataBuilder(term);
    })
  }
}

function dataBuilder(entity, query) {
  var payload = JSON.stringify({
    'entity': entity,
    'searchTerm': query
    'session': this.sessionKey // will be always undefined if bind(undefined,...) is used
  });
  return payload
}
var bindEx= dataBuilder.bind(undefined, "username");
var curryEx= dataBuilder.curry("username");

var usernameQuery = new Query("id1234",bindEx); // won't work, this.sessionKey will be undefined
usernameQuery = new Query("id1234",curryEx); // will  work, this.sessionKey will be id1234 in the DataBuilder
Run Code Online (Sandbox Code Playgroud)