Javascript использования Bind против карри?
Я пытаюсь понять разницу между curry
против 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*/ }
Реализация 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*/ };
я уже знаю, что curry
не является внутренней функцией (в отличие от bind
который находится в IE9+). Но до сих пор:
Почему я слышу, что люди продолжают говорить о curry
, В то время как они могут просто использовать bind
операция?
Единственное отличие - это контекст, который на самом деле находится только на bind
функция.
Пример:
Допустим, у меня есть эта функция:
function add(x,y,z)
{
return x+y+z;
}
Я мог бы сделать это с curry
:
alert(add.curry(2).curry(1)(4)) //7
Но я мог бы также сделать это с:
alert(add.bind(undefined,2).bind(undefined,1)(4)) //7
Я не понимаю, почему это curry
Термин функция существует, в то время как можно добавить фиктивный контекст в функцию связывания.
Что мне не хватает?
3 ответа
bind
вынуждает вас присоединять контекст к функции, используя curry
Вы можете отложить спецификацию контекста функции до вызова функции карри, что полезно во многих случаях.
рассмотрим следующий пример (не идеальный, просто чтобы проиллюстрировать идею):
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
Есть разница в намерениях.
Каррирование должно уменьшить количество аргументов, обычно, чтобы избежать многократного вызова функции с одинаковыми начальными аргументами. Например:
var celsiusToKelvin = add.curry(273.15);
bind() должен убедиться, что функция присоединена к объекту. Также может быть предложено средство каррирования, так что да, вы можете использовать bind() для карри (), но если вы хотите карри, карри () имеет меньше аргументов и показывает ваше намерение.
Я думаю, что это как-то связано с совместимостью со старыми браузерами, так как привязка доступна только с ECMAScript 5.
Смотрите это для списка .bind()
поддержка: http://kangax.github.io/es5-compat-table/
Кроме того, из того, что я слышал, большинство людей до сих пор используют карри, потому что оно выглядит чище, так как не нуждается в этом undefined
в аргументах.