柯里化与逆柯里化 
1. 柯里化(Currying) 
定义:柯里化是将一个多参数函数转换为单参数函数链式调用的过程,其特点是每个函数只接收一个参数,并返回接收下一个参数的函数,直到所有参数收集完毕后执行原函数。
代码示例 
javascript
// 普通加法函数
function add(a, b, c) {
  return a + b + c;
}
// 柯里化后的加法函数
function curriedAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
console.log(curriedAdd(1)(2)(3)); // 61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
自动柯里化函数实现 
javascript
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}
const curriedSum = curry((a, b, c) => a + b + c);
console.log(curriedSum(1)(2)(3)); // 61
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
应用场景 
- 参数复用:固定部分参数生成专用函数。javascriptconst addTen = curriedSum(10); console.log(addTen(20)(30)); // 601
 2
- 延迟执行:按需传入参数,灵活组合函数。
- 函数式编程:适配函数组合(如 compose、pipe)。
2. 逆柯里化(Uncurrying) 
定义:逆柯里化是将一个依赖于对象调用的方法转换为独立函数的过程,使其接收目标对象作为参数。核心是泛化方法的使用范围。
代码示例 
javascript
// 对象的push方法(依赖 Array 对象调用)
const obj = { 0: 'a', length: 1 };
Array.prototype.push.uncurried = function() {
  return Array.prototype.push.apply(arguments[0], [].slice.call(arguments, 1));
};
const uncurriedPush = Array.prototype.push.uncurried;
uncurriedPush(obj, 'b');
console.log(obj); // {0: 'a', 1: 'b', length: 2}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
通用逆柯里化函数实现 
javascript
Function.prototype.uncurry = function() {
  const fn = this;
  return function(context, ...args) {
    return fn.apply(context, args);
  };
};
// 逆柯里化Array的push方法
const push = Array.prototype.push.uncurry();
const array = [];
push(array, 1, 2);
console.log(array); // [1, 2]1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
应用场景 
- 借用其他对象方法:例如让类数组对象使用数组方法。javascriptconst slice = Array.prototype.slice.uncurry(); const args = { 0: 'a', 1: 'b', length: 2 }; console.log(slice(args, 0)); // ['a', 'b']1
 2
 3
- 统一处理不同对象的方法:如统一调用不同类的 toString方法。
- 兼容鸭子类型(Duck Typing):对不严格符合接口的对象也能操作。
核心区别 
| 特性 | 柯里化 | 逆柯里化 | 
|---|---|---|
| 目的 | 分步传递参数,生成函数链 | 泛化对象方法,使之以函数形式调用 | 
| 应用方向 | 多参数函数 → 单参数函数链 | 对象方法 → 独立函数 | 
| 典型场景 | 函数组合、参数复用 | 方法借用、跨对象操作 | 
总结 
- 柯里化:提升函数灵活性与复用性,适配高阶函数场景。
- 逆柯里化:打破对象方法的调用限制,便于跨类型操作。
 两者各有所长,柯里化更偏向函数式编程范式,逆柯里化则解决 JavaScript 原型方法的通用性问题。