const foo = function(x) { return x + 1 }
can be loosely written as const foo = x => x + 1
. The latter is called an arrow function
So
const canUser = (permission) => (permissions) => (guideSlug) => {
if (!permissions) return false;
const globalPermissions = permissions['*'] || {};
const guidePermissions = permissions[guideSlug] || {};
return globalPermissions[permission] || guidePermissions[permission] || false;
};
is same as
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;
}
}
};
This is called partial application or currying, both are kinda same I'm not sure which is the accurate term here.
Here's a case where it's useful...
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);
Here as you can see there's a lot a
s in the code which is kinda repetitive and less readable. Writing it in the following way solves the problem...
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
Another advantage of such pattern is that you can pass around fooA
to other function or if you want to store it in an abstraction of a
like const somethingRelevantToA = { foo: foo(a), bar: "some other prop of
a" }
.
Also you are reusing the logic if you want something like fooA
and fooB
and they have something in common like...
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 */
}
So basically instead of writing fooA
and fooB
separately you are writing foo
and thus reusing the logic.