柯里化实现的格式化输出拦截器函数通过分步传入“格式规则”和“原始值”,返回可复用、预设行为的函数,支持模板字符串、内置类型(如date)及函数式规则,具备可配置、可组合、延迟执行特性。

用柯里化实现统一格式化输出的拦截器函数,核心是把“格式规则”和“原始值”分两步传入,返回一个可复用、带预设行为的函数。它不是单纯做字符串拼接,而是让格式逻辑可配置、可组合、可延迟执行。
理解目标:什么是“格式化输出拦截器”
这类函数通常用于日志、API 响应、表单提交前的数据清洗等场景,比如:
- 所有数字输出补零到 2 位:
format('00')(4) → '04' - 所有字符串加前后括号:
format('(%s)')('hello') → '(hello)' - 日期统一转为
YYYY-MM-DD:format('date')('2023/5/1') → '2023-05-01'
关键在于:规则(如模板或类型标识)提前定好,值在后续调用时才传入——这正是柯里化的天然适用场景。
基础柯里化格式化函数(支持模板与类型)
下面是一个轻量、可扩展的实现,支持字符串模板(类似 printf)和内置类型处理:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const format = (rule) => {
// 预编译规则,避免每次重复解析
if (typeof rule === 'string') {
if (rule === 'date') {
return (input) => {
const d = new Date(input);
return d instanceof Date && !isNaN(d)
? `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
: '';
};
}
// 支持 '%s' 占位符模板,如 '【%s】'
const regex = /%s/g;
return (value) => rule.replace(regex, () => String(value));
}
// 支持函数式规则:format((x) => x.toUpperCase())('abc') → 'ABC'
if (typeof rule === 'function') {
return rule;
}
throw new Error('Unsupported format rule');
};
使用示例:
const toUpper = format(x => x.toUpperCase());
const asDate = format('date');
const withBrackets = format('【%s】');
console.log(toUpper('hello')); // 'HELLO'
console.log(asDate('2023/8/5')); // '2023-08-05'
console.log(withBrackets(123)); // '【123】'
进阶:支持多参数与管道式组合
若需更灵活(如金额格式化含千分位+小数),可进一步柯里化参数:
// formatNumber :: (decimalPlaces, thousandsSep, decimalSep) => (num) => string
const formatNumber = (decimals = 2, thousands = ',', decimal = '.') =>
(num) => {
const n = Number(num);
if (isNaN(n)) return '';
const [int, frac] = n.toFixed(decimals).split('.');
return `${Number(int).toLocaleString('en-US', { useGrouping: true, minimumIntegerDigits: 1 })}${frac ? decimal + frac : ''}`;
};
// 使用
const money = formatNumber(2, ',', '.');
console.log(money(1234567.891)); // '1,234,567.89'
还能和其它柯里化函数组合(如先转数字再格式化):
const safeParseFloat = format(parseFloat);
const toMoney = (x) => money(safeParseFloat(x));
toMoney('12345.678'); // '12,345.68'
实用建议与注意事项
写这类拦截器时注意几点:
- 错误防御优先:对非法输入(null、undefined、NaN)返回空字符串或原样透传,避免中断流程
- 避免副作用:格式化函数应纯函数,不修改原始数据、不依赖外部状态
-
模板引擎别过度设计:简单项目用
%s足够;复杂需求可引入util.format或intl.NumberFormat等标准 API - 性能敏感场景缓存编译结果:比如正则、日期解析器、Intl 实例可在闭包中复用
柯里化本身不解决格式逻辑,但它让“配置即函数”变得自然——规则固化后,调用干净利落,也方便单元测试和按需注入。

















