Compose function

The compose function tiled functions that require nested execution, where the return value of one function is taken as an argument to another function. Let’s consider a simple requirement:

Given an input value x, add 10 to the value and multiply the result by 10Copy the code

This requirement is very simple, just a calculation function:

const calculate = x => (x + 10) * 10; let res = calculate(10); console.log(res); / / 200Copy the code

But according to the functional programming we talked about earlier, we can split the complex steps into several simple reusable steps, so we separated an addition function and a multiplication function:

const add = x => x + 10; const multiply = x => x * 10; Multiply (add(10)); multiply(add(10)); multiply(add(10)); console.log(res); // Still 200Copy the code

The calculation method of the above is the nested function execution, and we will compose role is nested execution method as a parameter to tile, nested execution, the inside of the method is also the most begin to execute the right way, then to the left back, we compose method is started from the right of the parameters, so our goal is very clear, We need a compose method that looks something like this:

Multiply = compose(multiply, add)(10); multiply = compose(multiply, add)Copy the code

Before we get to that let’s look at the array.prototype.reduce function we need to use

Array.prototype.reduce

The reduce method of an array can implement an accumulator effect that takes two arguments, the first an accumulator method and the second an initialization value. The first parameter is the last computed value, and the second parameter is the current value of the array. These two parameters are mainly used. The last two parameters are the current index and the current array.

const arr = [[1, 2], [3, 4], [5, 6]]; Const flatArr = arr.reduce((prevRes, item) => prevres.concat (item), []); // prevRes = prevres.concat (item); console.log(flatArr); // [1, 2, 3, 4, 5, 6]Copy the code

Array.prototype.reduceRight

Array. The prototype. Will reduce from left to right to iterate, if needed from right to left iterations, with Array. Prototype. ReduceRight

const arr = [[1, 2], [3, 4], [5, 6]]; Const flatArr = arr.reduceright ((prevRes, item) => prevres.concat (item), []); console.log(flatArr); // [5, 6, 3, 4, 1, 2]Copy the code

The compose method that how to achieve this, with the help of an Array is needed here. Prototype. ReduceRight:

Const compose = function(){const args == [multiply, add] const args = [].slice.apply(arguments); return function(x) { return args.reduceRight((res, cb) => cb(res), x); }} let calculate = compose(multiply, add); let res = calculate(10); console.log(res); // Still 200Copy the code

The compose function above is even more concise using ES6:

const compose = (... args) => x => args.reduceRight((res, cb) => cb(res), x);Copy the code

Redux’s middleware is implemented in Compose, and the loaders in WebPack are loaded from right to left because they are also implemented in Compose.

Pipe function

The pipe function does the same thing for compose, tiling the parameters from left to right. Let’s implement, just change reduceRight into Reduce:

const pipe = function(){ const args = [].slice.apply(arguments); return function(x) { return args.reduce((res, cb) => cb(res), x); }} let calculate = pipe(add, multiply); let res = calculate(10); console.log(res); // Still 200Copy the code

ES6 writing:

const pipe = (... args) => x => args.reduce((res, cb) => cb(res), x)Copy the code

At the end of this article, thank you for your precious time to read this article. If this article gives you a little help or inspiration, please do not spare your thumbs up and GitHub stars. Your support is the motivation of the author’s continuous creation.

Welcome to follow my public numberThe big front end of the attackThe first time to obtain high quality original ~

“Front-end Advanced Knowledge” series:Juejin. Im/post / 5 e3ffc…

“Front-end advanced knowledge” series article source code GitHub address:Github.com/dennis-jian…