# 「前端进阶」彻底弄懂函数组合

·  阅读 15948

## 什么是组合

function compose(...fns){
//忽略
}
// compose(f,g)(x) === f(g(x))
// compose(f,g,m)(x) === f(g(m(x)))
// compose(f,g,m)(x) === f(g(m(x)))
// compose(f,g,m,n)(x) === f(g(m(n(x))))
//···

## 应用 compose 函数

let n = '3.56';
let data = parseFloat(n);
let result = Math.round(data); // =>4 最终结果

compose函数改写：

let n = '3.56';
let number = compose(Math.round,parseFloat);
let result = number(n); // =>4 最终结果

let splitIntoSpaces = str => str.split(' ');
let count = array => array.length;

let countWords = compose(count,splitIntoSpaces);

let result = countWords('hello your reading about composition'); // => 5

## 开发中组合的用处

let str = 'jspool'

//先转成大写，然后逆序
function fn(str) {
let upperStr = str.toUpperCase()
return upperStr.split('').reverse().join('')
}

fn(str) // => "LOOPSJ"

"jspool" => ["J","S","P","O","O","L"]

let str = 'jspool'

function stringToUpper(str) {
return str.toUpperCase()
}

function stringReverse(str) {
return str.split('').reverse().join('')
}

let toUpperAndReverse = compose(stringReverse, stringToUpper)
let result = toUpperAndReverse(str) // "LOOPSJ"

let str = 'jspool'

function stringToUpper(str) {
return str.toUpperCase()
}

function stringReverse(str) {
return str.split('').reverse().join('')
}

function stringToArray(str) {
return str.split('')
}

let toUpperAndArray = compose(stringToArray, stringToUpper)
let result = toUpperAndArray(str) // => ["J","S","P","O","O","L"]

let str = 'jspool'

function stringToUpper(str) {
return str.toUpperCase()
}

function stringReverse(str) {
return str.split('').reverse().join('')
}

function getThreeCharacters(str){
return str.substring(0,3)
}

function stringToArray(str) {
return str.split('')
}

let toUpperAndGetThreeAndArray = compose(stringToArray, getThreeCharacters,stringToUpper)
let result = toUpperAndGetThreeAndArray(str) // => ["J","S","P"]

## 实现组合

// compose(f,g)(x) === f(g(x))
// compose(f,g,m)(x) === f(g(m(x)))
// compose(f,g,m)(x) === f(g(m(x)))
// compose(f,g,m,n)(x) === f(g(m(n(x))))
//···

function compose(f,g){
return function(x){
return f(g(x));
}
}

function compose(f,g,m){
return function(x){
return f(g(m(x)));
}
}

function compose(...fns){
return function(x){
//···
}
}

function compose(...fns){
return function(x){
return fns.reduceRight(function(arg,fn){
return fn(arg);
},x)
}
}

## 实现管道

compose的数据流是从右至左的，因为最右侧的函数首先执行，最左侧的函数最后执行！

function pipe(...fns){
return function(x){
return fns.reduce(function(arg,fn){
return fn(arg);
},x)
}
}

## 写在最后

• 文中如有错误，欢迎在评论区指正，如果这篇文章帮到了你，欢迎点赞关注
• 本文同步首发与github，可在github中找到更多精品文章，欢迎Watch & Star ★
• 后续文章参见：计划