JavaScript通过闭包实现偏函数,可固定部分参数并返回新函数;bind方法是原生支持但灵活性较低;增强版支持占位符跳过参数,核心均为闭包维持预设参数。

JavaScript 本身没有内置的偏函数(Partial Application)语法,但靠闭包能自然、轻量地实现参数固定——把一部分参数“存”在外部作用域里,返回的新函数只接收剩下那些。
用闭包手动封装预设参数
最直接的方式是写一个工厂函数,接收原函数和要固定的参数,返回一个新函数。这个新函数内部通过闭包访问已传入的参数,并在调用时合并剩余参数执行原函数。
- 闭包让预设参数不随调用消失,每次调用都“记得”它们
- 不需要修改原函数,也不依赖默认参数或 this 绑定
- 适合配置复用,比如固定 API 基础路径、日志前缀、单位换算系数等
示例:
function partial(fn, ...preset) {
return function(...rest) {
return fn(...preset, ...rest);
};
}
立即学习“Java免费学习笔记(深入)”;
const addTen = partial((a, b) => a + b, 10);
addTen(5); // → 15
用 bind 实现(本质也是闭包)
Function.prototype.bind 是语言层面对偏函数的原生支持,它内部就依赖闭包来保存 this 和部分参数。
- 第一个参数指定 this 值(可为 null),后续参数即为预设参数
- 返回函数调用时,自动把预设参数放在前面,再拼接新传入的参数
- 比手写更简洁,但灵活性略低(比如不能跳过中间参数)
示例:
const multiplyByTwo = (x, y) => x * y;
const double = multiplyByTwo.bind(null, 2);
double(7); // → 14
支持占位符的增强版(模拟 Lodash 的 partial)
真实项目中常需要“跳过”某些位置的参数,比如固定第二个参数而让第一个之后再传。这时可在闭包中记录占位符(如 `_`),运行时按位置填充。
- 用数组保存预设参数,遇到占位符就留空
- 调用时把 rest 参数依次填入空位,再拼成完整参数列表
- 核心仍是闭包维持 preset 数组和占位逻辑
示例思路:
const _ = {}; // 占位符标记
function partialWithHole(fn, ...preset) {
return function(...rest) {
let args = [...preset];
let restIndex = 0;
for (let i = 0; i if (args[i] === _) args[i] = rest[restIndex++];
}
return fn(...args.concat(rest.slice(restIndex)));
};
}
和柯里化的关键区别
偏函数不是柯里化:它不强制单参数调用,也不拆解所有参数;它只是“提前填几个,剩下的以后给”。闭包在这里的作用很纯粹——做一次性的参数快照,而不是递归累积。
- 偏函数:一次固定多个,返回函数接收剩余全部(如 fn(a, b, c) → partial(fn, 1)(2, 3))
- 柯里化:必须逐步传,每次只收一个,靠嵌套闭包链式记忆(如 fn(1)(2)(3))
- 两者都靠闭包,但结构目标不同:偏函数重复用,柯里化重组合与推导


















