问题
I'm trying to understand the difference between curry
vs bind
.
The implementation of bind
is :
/*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*/ }
The implementation of curry
is :
/*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*/ };
I already know that curry
is not an internal function (unlike bind
which is in IE9+). But still:
Why do I hear people keep talking about curry
, While they can simply use bind
operation ?
The only difference is the context which is actually found only at the bind
function.
differences

Example :
Let's say I have this function :
function add(x,y,z)
{
return x+y+z;
}
I could do it with curry
:
alert(add.curry(2).curry(1)(4)) //7
But I could also do it with :
alert(add.bind(undefined,2).bind(undefined,1)(4)) //7
I don't understand why this curry
term function exists while it is possible to add a dummy context to the bind function.
What am I missing ?
回答1:
bind
forces you to attach a context to the function, while by using curry
, you can delay the specification of function context until invoking the curried function, useful in many cases.
consider the following example (not the perfect one, just to illustrate the idea):
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
回答2:
There is a difference in intention.
Currying is to reduce the number of arguments, usually to avoid calling a function a lot with the same initial arguments. For example:
var celsiusToKelvin = add.curry(273.15);
bind() is to make sure that a function is attached to an object. It also happens to offer a currying facility, so yes you can use bind() to curry(), but if you want to curry, curry() has fewer arguments and shows your intention.
回答3:
I'd think it has something to do with compatibility with older browsers as bind is only available since ECMAScript 5.
See this for a list of .bind()
support: http://kangax.github.io/es5-compat-table/
Also from what I've heard, most people still use curry because it looks cleaner as it doesn't need that extra undefined
in the arguments.
来源:https://stackoverflow.com/questions/22127889/javascript-usages-of-bind-vs-curry