「面试」-函数柯理化

668 阅读2分钟

PS:参考一些博客,整理出来供自己复习使用~

什么是函数柯理化

函数柯里化(curry)是函数式编程里面的概念。curry的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

简单点来说就是:每次调用函数时,它只接受一部分参数,并返回一个函数,直到传递所有参数为止。

const add = (x, y) => x + y;
add(1, 2);

改成每次只接受一个参数的函数

const add = x => y => x + y;
add(1)(2);

add(1)(2)(3)

const add = x => y => z => x + y + z;
console.log(add(1)(2)(3));

看起来并不是那么难,但是如果面试官的要求是实现一个add 函数,同时支持下面这几种的用法呢?又或者也不知道具体会传多少个参数?

实现思路:

主要思路是什么呢,要判断当前传入函数的参数个数 (args.length) 是否大于等于原函数所需参数个数 (fn.length) ,如果是,则执行当前函数;如果是小于,则返回一个函数。

const curry = (fn, ...args) => 
    // 函数的参数个数可以直接通过函数数的.length属性来访问
    args.length >= fn.length // 这个判断很关键!!!
    // 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
    ? fn(...args)
    /**
     * 传入的参数小于原始函数fn的参数个数时
     * 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
    */
    : (..._args) => curry(fn, ...args, ..._args);

function add1(x, y, z) {
    return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));

lodash是一个很强大的工具函数库,比如 节流,防抖,深拷贝等等,只要引入 lodash ,我们就可以直接使用。

柯理化的作用

主要有3个作用: 参数复用提前返回延迟执行

我们来简单的解释一下:

参数复用:拿上面f这个函数举例,只要传入一个参数z,执行,计算结果就是 1 + 2 + z 的结果,1 和 2 这两个参数就直接可以复用了。

提前返回 和 延迟执行 也很好理解,因为每次调用函数时,它只接受一部分参数,并返回一个函数(提前返回),直到(延迟执行)传递所有参数为止。