<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>compose实现函数调用扁平化</title>
</head>
<body>
<script>
let fn1 = function (x) {
return x + 10;
};
let fn2 = function (x) {
return x * 10;
};
let fn3 = function (x) {
return x / 10;
};
function compose(...funcs) {
// ...funcs :代表传递的函数集合
// 执行一个函数后紧接着又把它执行一遍,就是return一个函数,这是柯理化函数编程思想
return function proxy(...args) {
// args : 第一次调用函数传递的参数集合
let len = funcs.length;
if (len === 0) {
// =>一个函数都不需要执行,直接返回ARGS
return args;
}
if (len === 1) {
// =>只需要执行一个函数,把函数执行,把其结果返回即可
return funcs[0](...args);
}
return funcs.reduce((x, y) => {
return typeof x === "function" ? y(x(...args)) : y(x);
})
}
}
// redux源码中有的compose函数
// function compose(...funcs) {
// if (funcs.length === 0) {
// return arg => arg
// }
// if (funcs.length === 1) {
// return funcs[0]
// }
// return funcs.reduce((a, b) => (...args) => a(b(...args)))
// }
// =>compose函数调用的扁平化
console.log(compose()(5)); //5 执行一个函数后紧接着又把它执行一遍,就是return一个函数,这是柯理化函数编程思想
console.log(compose(fn1)(5)); //=>5+10 = 15
console.log(compose(fn1, fn2)(5)); //=> fn1(5)=15 fn2(15)=15 ...
console.log(compose(fn1, fn2, fn1, fn3)(5)); //=>16
// 数组的reduce方法
/* let arr = [12, 23, 34, 56];
let total = arr.reduce((x, y) => {
// => x:上一次处理的结果
// => y:数组中某一项
// reduce不传第二个参数:x初始值是第一项的值,然后每一次返回的结果作为下一次x的值
// reduce传第二个值,x的初始值就是第二个参数值
console.log(x, y)
return x + y;
}, 0)
console.log(total);
*/
/* let x = fn1(5);
x = fn2(x);
x = fn1(x);
x = fn3(x);
console.log(x) //=>16
*/
// console.log(fn3(fn1(fn2(fn1(5))))); //=> (((10+5)*10)+10)/10 =>16
</script>
</body>
</html>
关于数组的reduce方法,可见runoob.com/jsref/jsref-reduce.html,
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce