const foo = function(x) { return x + 1 }
можно свободно записать как const foo = x => x + 1
. Последний называется функция стрелки
Итак
const canUser = (permission) => (permissions) => (guideSlug) => {
if (!permissions) return false;
const globalPermissions = permissions['*'] || {};
const guidePermissions = permissions[guideSlug] || {};
return globalPermissions[permission] || guidePermissions[permission] || false;
};
совпадает с
const canUser = function(permission) {
return function(permissions) {
return function (guideSlug) {
if (!permissions) return false;
const globalPermissions = permissions['*'] || {};
const guidePermissions = permissions[guideSlug] || {};
return globalPermissions[permission] || guidePermissions[permission] || false;
}
}
};
Это называется частичное применение или карри , оба они примерно одинаковые, я не уверен, какой здесь точный термин.
Вот случай, когда это полезно ...
const foo = (x, y) => { /* something to be done with x and y */ }
let x = foo(a,b);
let y = foo(a,c);
let z = foo(a,d);
Здесь, как вы можете видеть, в коде много a
s, которые являются несколько повторяющимися и менее читаемыми. Запись его следующим образом решает проблему ...
const foo = x => y => { /* something to be done with x and y */ }
let fooA = foo(a); // fooA is the `y => {}` function with `x = a` "partially applied"
let x = fooA(b);
let y = fooA(c);
let z = foo(a)(d); // you can still write it like this
Еще одним преимуществом такого шаблона является то, что вы можете передавать fooA
другой функции или, если хотите сохранить ее в абстракции a
, например const somethingRelevantToA = { foo: foo(a), bar: "some other prop of
a " }
.
Также вы повторно используете логику, если хотите что-то вроде fooA
и fooB
, и у них есть что-то общее, например ...
const foo = x => y => {
/* piece of code independent of x (this is being reused) */
/* piece of code dependent only on y or x and y both */
}
Таким образом, вместо написания fooA
и fooB
отдельно вы пишете foo
и, таким образом, повторно используете логику.