The use of a function called Currying
Currization, also known as partial evaluation, means passing parameters to a function in steps, partially applying the parameters each time, and returning a more specific function that accepts the remaining parameters. Layers of such functions that accept partial parameters can be nested in between, until the final result is returned.
What’s the good of that?
- Parameter multiplexing: To reduce the repeated passing of invariant parts of the parameter
- Delay calculation: throttling and anti-shaking
- Confirmation in advance
Parameter reuse example
Function check(reg, TXT) {return reg. Test (TXT); } console.log(check(/\d+/g, "test1")); // =>true console.log(check(/\d+/g, "testtest")); // =>falseCopy the code
Function curryingCheck(reg) {return function (TXT) {return reg.test(TXT); }; } let hasNumber = curryingCheck(/\d+/g); let hasLetter = curryingCheck(/[a-z]+/g); / / check the console log (hasNumber (" test1 ")); // =>true console.log(hasNumber("testtest")); // =>false console.log(hasLetter("21212")); / / = > false / / check the console log (curryingCheck (\ d + / g) (" asda1 ")); // =>true console.log(curryingCheck(/\d+/g)("asda")); // =>falseCopy the code
Parameter reuse, the use of the closure principle, so that the previous transmission over the parameter is not released.
Parameters of reuse
/** * const add = (... args) => args.reduce((a, b) => a + b); function curryingSum(func) { const args = []; return function result(... rest) { if (rest.length === 0) { return func(... args); } else { args.push(... rest); return result; }}; }Copy the code
This function adds the values of internal parameters when they are empty, caches them when they are not empty, and adds them when they are empty, again using closures.
Confirmation in advance
This feature is often used to make some judgments about browser compatibility and initialize the API. For example, we currently use addEventListener to listen for events. However, some older browsers do not support this method, so we can make a judgment before using it. You can then omit this step.
function addEvent(type, el, fn, capture = false) { if (window.addEventListener) { el.addEventListener(type, fn, capture); } else if (window.attachEvent) { el.attachEvent("on" + type, fn); }}Copy the code
Generic encapsulation methods
Function curryingFun (fn, length) {/ / the first call to obtain function fn parameters, the length of the subsequent calls to obtain fn the length of the remaining parameters length = length | | fn. Length; // The curryingFun wrapper returns a new function that takes... args return function (... Args) {return args. Length >= length? Fn. apply(this, args) : // The new fn function is returned by bind. Args argument, not executed), new length is the length of the remaining fn arguments curryingFun(fn.bind(this,... args), length - args.length); }; }Copy the code
ES6 writing
const curryingFun = (fn, arr = []) => (... args) => ((arg) => (arg.length === fn.length ? fn(... arg) : curryingFun(fn, arg)))([ ...arr, ...args, ]);Copy the code
check
const fn = curryingFun(function (a, b, c) {
console.log([a, b, c]);
});
fn("a", "b", "c"); // ["a", "b", "c"]
Copy the code
const fn2 = curryingFun(function (a, b, c) { console.log(a + b + c); }); fn2(1)(2)(3); . / / 6Copy the code
In terms of corrifying properties
- Accessing arguments objects is generally a bit slower than accessing named arguments
- Some older browsers are quite slow to implement arguments.length
- Use fn.apply(…) And fn. Call (…). It’s usually better than calling fn(…) directly. A little bit slowly
- Creating lots of nested scopes and closures can be costly, both in memory and speed
On the meaning of Currization
Make functions completely “take one argument; return one value” and take advantage of closures to eliminate redundant argument passing, improving readability and code quality.
Reference documentation
-
Deep high order function application of curry < wood Yi Yang > www.imooc.com/article/291…
-
Currie, JS function flowsands www.jianshu.com/p/2975c25e4…