compose 就是组合函数,将子函数串联起来执行,一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,会像多米诺骨牌一样推导执行后续函数。
const greeting = name => `Hello ${name}`
const toUpper = str => str.toUpperCase()
toUpper(greeting('Onion')) // HELLO ONION
compose 函数的特点
- compose 接受函数作为参数,从右向左执行,返回类型函数
- fn()全部参数传给最右边的函数,得到结果后传给倒数第二个,依次传递
var compose = function(...args) {
var len = args.length // args函数的个数
var count = len - 1
var result
return function func(...args1) {
// func函数的args1参数枚举
result = args[count].call(this, args1)
if (count > 0) {
count--
return func.call(null, result) // result 上一个函数的返回结果
} else {
//回复count初始状态
count = len - 1
return result
}
}
}
举例:
var greeting = (name) => `Hello ${name}`
var toUpper = str => str.toUpperCase()
var fn = compose(toUpper, greeting)
console.log(fn('jack'))
大家熟悉的 webpack 里面的 loader 执行顺序是从右到左,是因为webpack 选择的是 compose 方式,从右到左依次执行 loader,每个 loader 是一个函数。
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
]
如上,webpack 使用了 style-loader 和 css-loader,它是先用 css-loader 加载.css 文件,然后 style-loader 将内部样式注入到我们的 html 页面。
webpack 里面的 compose 代码如下:
const compose = (...fns) => {
return fns.reduce(
(prevFn, nextFn) => {
return value =>prevFn(nextFn(value))
},
value => value
)
}