函数式编程-函数的柯里化
本文最后更新于:2022年4月22日 上午
函数的柯里化的实现,以及 Vue
,redux-chunk
中柯里化的体现
在函数式编程中,函数的柯里化有利于我们将一个合理的组织代码,虽然不理解这个概念也不会影响编码,但是理解的这个概念,可以编写复用性更高,可维护性更好的代码
在计算机科学中,柯里化 (英语:Currying),又译为卡瑞化 或加里化 ,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
JavaScript 中柯里化的实现
function currying(fn) {
function innerCurrying(...args) {
// 如果形参的个数大于等于函数需要的参数,则直接调用函数
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
// 如果参数不够,则返回一个新的函数,用来接收剩余的参数,在函数内部递归的调用自身,直到形参的个数达到要求
return function (...surplusArgs) {
return innerCurrying.apply(this, [...args, ...surplusArgs]);
};
}
}
return innerCurrying;
}
function foo(param1, param2, param3) {
return param1 + param2 + param3;
}
// 柯里化之后的函数
const newFn = currying(foo);
console.log(newFn(10)(20)(30)); // 60
console.log(newFn(10, 20)(30)); // 60
console.log(newFn(10)(20, 30)); // 60
console.log(foo(10, 20, 30)); // 60
参数不确定的情况
函数的组合
const add1 = (num) => num + 1;
const mul2 = (num) => num * 2;
const div3 = (num) => num / 3;
const compose = (...funcs) => {
return (value) => {
return funcs.reduceRight((prev, next) => next(prev), value);
};
};
const operate = compose(div3, mul2, add1);
const result = operate(1);
console.log('result:', result); // 1.333333333
使用 promise 改写函数的组合
const add1 = (num) => num + 1;
const mul2 = (num) => num * 2;
const div3 = (num) => num / 3;
const compose = (...fns) => {
return (num) => fns.reduceRight((promise, fn) => promise.then(fn), Promise.resolve(num));
};
const operate = compose(div3, mul2, add1);
const result = operate(1);
result.then((res) => {
console.log('promise result:', res); // 1.333333333
});
Vuejs 源码中 柯里化的应用
在 Vue3
后,我们创建应用的方式都变成了类似于以下的方式,从 vue
中导出 createApp
然后通过 createApp
来注册整个应用
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
createApp 源码
createApp
的源码位于 目录packages\runtime-core\src\renderer.ts
中 baseCreateRenderer
函数下,可以看到,该函数最终返回以下几个内容
createApp
是通过 createAppAPI
函数返回的函数
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate)
}
在 createAppAPI
中,接受一个 render
, hydrate
,然后返回 createApp
,我们知道vue在渲染时,最主要是通过调用 render
函数来进行渲染的,所以如此做的原因是,在进行一些跨端渲染的时候,例如小程序端,开发者可以自定义实现 render
export function createAppAPI<HostElement>(
render: RootRenderFunction,
hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {
return function createApp(rootComponent, rootProps = null) {
... 省略
}
}
redux-chunk 中 柯里化的体现
在 redux-chunk 源码中也有函数柯里化的体现
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => (next) => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。