1const curry = (fn, ...args) =>
2 // 函数的参数个数可以直接通过函数数的.length属性来访问
3 args.length >= fn.length // 这个判断很关键!!!
4 // 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
5 ? fn(...args)
6 /**
7 * 传入的参数小于原始函数fn的参数个数时
8 * 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
9 */
10 : (..._args) => curry(fn, ...args, ..._args);
11
12function add1(x, y, z) {
13 return x + y + z;
14}
15const add = curry(add1);
16console.log(add(1, 2, 3));
17console.log(add(1)(2)(3));
18console.log(add(1, 2)(3));
19console.log(add(1)(2, 3));
20复制代码
柯里化有什么作用
主要有3个作用: 参数复用、提前返回和 延迟执行
我们来简单的解释一下: 参数复用:拿上面 f
这个函数举例,只要传入一个参数 z
,执行,计算结果就是 1 + 2 + z
的结果,1 和 2 这两个参数就直接可以复用了。
提前返回 和 延迟执行 也很好理解,因为每次调用函数时,它只接受一部分参数,并返回一个函数(提前返回),直到(延迟执行)传递所有参数为止。
1/**
2 * @description: 将函数柯里化的工具函数
3 * @param {Function} fn 待柯里化的函数
4 * @param {array} args 已经接收的参数列表
5 * @return {Function}
6 */
7const currying = function(fn, ...args) {
8 // fn需要的参数个数
9 const len = fn.length
10 // 返回一个函数接收剩余参数
11 return function (...params) {
12 // 拼接已经接收和新接收的参数列表
13 let _args = [...args, ...params]
14 // 如果已经接收的参数个数还不够,继续返回一个新函数接收剩余参数
15 if (_args.length < len) {
16 return currying.call(this, fn, ..._args)
17 }
18 // 参数全部接收完调用原函数
19 return fn.apply(this, _args)
20 }
21}
个人笔记记录 2021 ~ 2025