用通俗易懂的语言讲懂什么是—函数柯里化

331 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

柯里化?

柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

我的理解就是:将参数从一次性传入调用变为一次或多次传入调用

原来的函数:

function add(x, y, z) {
  return x + y + z;
}
console.log(add(1, 2, 3)); // 6

柯里化实现:

function add(a) {
    return function(b) {
        return function(c) {
            return a + b + c;
        }
    }
}
console.log(add(1)(2)(3)); // 6
//对应了我上面说的:将参数从一次性传入调用变为一次或多次传入调用

哪如果有多层呢?我们能一直return嵌套下去吗?

所以我们要实现一个通用的柯里化函数来实现将一个函数柯里化!

我曾经的误解就是函数柯里化就是直接对原函数进行改造,后来发现柯里化其实是写一个curry函数然后传入原函数,然后我们对curry函数返回的函数进行多次调用,并不改变原函数。

function curry (fn, currArgs) {
    return function() {
        // 将具有length属性的arguments转换为数组
        let args = [].slice.call(arguments); 

        // 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
        if (currArgs !== undefined) {
            args = args.concat(currArgs);
        }

        // 递归调用
        if (args.length < fn.length) {
            return curry(fn, args);
        }

        // 递归出口
        return fn.apply(null, args);  // null表示没有需要替代的对象
    }
}

解析一下curry的写法:

fn是需要柯里化的函数,currArgs是上次调用到这次调用传参之前所有的参数,当参数数量等于fn参数数量的时候说明参数传递完毕执行fn。

调用方式:

function sum(a, b, c) {
    console.log(a + b + c);
}
const fn = curry(sum);

fn(1, 2, 3); // 6
fn(1, 2)(3); // 6
fn(1)(2, 3); // 6
fn(1)(2)(3); // 6

!!!重点:假如我们a的值是固定的后面两个值不一样怎么调用呢?

function sum(a, b, c) {
    console.log(a + b + c);
}
const fn = curry(sum, 1);

fn(2, 3); // 6
fn(2)(3); // 6
fn(2, 3); // 6
fn(2)(3); // 6

柯里化的作用:就是假如前面的参数固定我们不用每次都传入相同的参数,只需传入不同的参数即可