目录
纯函数
可缓存
loadsh中memoize缓存函数简单实现
副作用
示例
接口的幂等性
函数的柯里化
lodsh中的curry方法简单实现
lodash中的fp模块
函数的组合
lodash中的flowRight方法简单实现
函子Functor
IO函子
其它函子详细介绍
对于相同的输入函数,始终得到相同的输出。
因为存函数对相同的输入始终有相同的输出,所以可以把纯函数的的结果缓存起来。
function memoize(f){let cache = {}return function () {let arg_str = JSON.stringify(arguments);cache[arg_str] = cache[arg_str] || f.apply(f, arguments);return cache[arg_str];}
}
function getSum(a, b){console.log('执行了')return a + b;
}
const cacheSum = memoize(getSum);
cacheSum(1,2);
cacheSum(1,2);
如果函数依赖外部的状态就无法保证输出相同,就会带来副作用(让一个函数变为不纯)。
例如下面当mini改变时就会给checkAge带来副作用(相同的输入,输出不同)。
let mini = 18;
function checkAge(age) {return age >= mini
}
副作用一般来源于:
接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。
当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变),然后返回一个新的函数接收剩下的参数,返回结果。
function checkAge(min, age) {return age >= min;
}
// 柯里化后
function checkAge(min) {return function(age) {return age >= min;}
}
function curry(func) {return function curriedFn(...args) {if(args.length < func.length) {return function() {// 注意arguments参数是类数组需要通过Array.from转化为数组return curriedFn(...args.concat(Array.from(arguments)))}}return func(...args)}
}
function getSum(a, b, c){return a + b + c;
}
const curried = curry(getSum);
curried(1, 2, 3);
const sumBC = curried(1)
sumBC(2, 3);
其中map、split等函数都用了函数柯里化。当只传入一个参数时,返回的是一个函数。
const fP = require('lodash/fp');
fp.map(fp.toUpper,['a', 'b', 'c']);
const toUpper = fp.map(fp.toUpper);
toUpper(['a', 'b', 'c']);
fp.split(' ', 'hello world');
const split = fp.split(' ');
split('hello world');
如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数和并成一个函数(g(f(x)) => h(g,f))。
function flowRight(...args) {return function(value) {return args.reverse().reduce(function(acc, fn) {return fn(acc)}, value)}
}
const reverse = arr => arr.reverse()
const first = arr => arr[0]
const f = flowRight(first, reverse)
f([1, 2, 3])
数组reduce方法介绍
JavaScript中常用函数方法(数组篇)_YF-SOD的博客-CSDN博客_javascript数组函数
一个特殊的容器,通过一个普通的对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理(变形关系)。
容器:包含值和值的变形关系,这个变形关系就是函数。
class Container {static of (value) {return new Container(value)}constructor (value) {this._value = value}map (fn) {return this._value ? Container.of(fun(this._value)) : Container.of(null)}
}
let r = Container.of(4).map(x => x * x)
IO函子中的_value是一个函数,这里把函数作为值来处理。
IO函子可以把不纯的动作存储在_value中,延迟执行这个不纯的操作,把不操作交给调用者处理。
const fp = require('lodash/fp')
class IO {static of (x) {return new IO(function () {return x;})}constructor (fn) {this._value = fn}map(fn) {return new IO(fp.flowRight(fn, this._value))}
}
let r = IO.of(process).map(p => p.execPath)
r._value()// 返回该文件路径
函子(Functor、Pointed、Maybe、Either、Mona式d、IO、Ap) - 知乎