函数式编程
假如目前有一个需求,把数组的每一项+1
1.初级程序员的写法
let arr = [1,2,3,4];
let newArr = []
for(let i = 0; i< arr.length; i++) {
newArr.push(arr[i] + 1)
}
2.好一点的程序员的写法
let newArr = (arr) => {
let res = [];
arr.map((item) => {
res.push(item + 1)
})
return res;
}
newArr(arr);
但是这两种写法都是命令式编程不是灵活的写法,代码是不能复用的,当需求变更之后,代码就需要改动,重复的事情需要多次操作。 所以在代码书写过程中,使用函数式编程是一种更好一些的方式。
let arr = [1,2,3,4]
let newArr = (arr, fn) => {
let res = [];
for(let i = 0; i < arr.length; i++) {
res.push(fn(arr[i]));
}
return res;
}
let add = (item) => item + 5;
let sum = newArr(arr, add);
采用函数式编程的方式可以很方便的用来获取不同需求的结果,例如乘法,减法等
纯函数
如果函数的调用参数相同,会永远返回相同的结果,它不依赖程序执行期间函数外部任何状态或者数据的变化,只依赖其输入的参数
let discount = 0.8;
function getPrice(price) {
return price * discount;
}
getPrice(100);
discount = 0.5;
getPrice(100);
上面的例子,每次调用getPrice函数传入的参数都是100但是因为要从外部获取discount的值会在外部变化,导致getPrice的值会变化,这个函数就不是纯函数。
function getPrice(price, discount) {
return price * discount;
}
getPrice(100, 0.8);
像这样所有的值,都由参数决定的,就是纯函数(没有副作用)
函数副作用
函数调用时会对主调用函数产生附加的影响,例如修改全局变量,会使代码维护变得困难。
compose函数
将需要嵌套执行的函数平铺,嵌套执行指的是,一个函数的返回值将作为另一个函数的参数。conpose函数主要是搜集函数,并且函数的执行是从右到左的。
实现一个数+10再*10的方式
复合函数实现
let add = x => x + 10;
let multiply = y => y * 10;
let compose = (f,g) => {
return (x) => {
return f(g(x));
}
}
let result = compose(multiply, add);
可以复用的函数
let add = x => x + 10;
let multiply = y => y * 10;
let compose = function() {
// arguments 没有slice函数,但是[]有,这种方法可以给arguments绑定一个slice方法
let args = [].slice.call(arguments);
return function(x) {
return args.reduceRight((res, cb) => {
return cb(res);
}, x)
}
}
let result = compose(multiply, add);
arguments 可以得到函数传入的参数

es6 的写法
let add = x => x + 10;
let multiply = y => y * 10;
const compose = (...args) => (x) => {
args.reduceRight((res, cb) => {
cb(res)
}, x)
}
let result = compose(multiply, add);
pipe函数
pipe函数执行从左向右
let add = x => x + 10;
let multiply = y => y * 10;
const pipe = (...args) => x => args.reduce((res, cb) => cb(res), x);
let result = pipe(add, multiply);
console.log('-------------result-------------------', result(10))