JS柯里化

作者: pq217 | 来源:发表于2022-04-02 18:16 被阅读0次

前言

柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

正文

简单柯里化

假设有一个数组,要对其中每一个元素进行同样操作,比如加一或加二

const arr1 = [0, 1, 2, 3];
let   arr2 = arr1.map(e => e+1); //加一
let   arr3 = arr1.map(e => e+2); //加二

那么是根据情况加不同的值,又不依赖全局变量,怎么处理,于是想把map里的1,2变成参数,但是通过map无法传递该参数,以下一个普通简单写法

let func = function (arr,add) {
    arr = arr.map(e => e + add)
    return arr;
}
const arr1 = [0, 1, 2, 3];
let arr2 = func(arr1,3);

柯里化就是下面

let func = function (arr) {
    return function (add) {
        let arr_add = arr.map(e => e + add)
        return arr_add;
    }
}
const arr1 = [0, 1, 2, 3];
let arr2 = func(arr1)(3);

这是一种简单的柯里化,上面的func方法相当于是一个函数工厂,返回的是一个函数,也可以直接func2 = func(arr1),后面在灵活的根据某个值n执行func2(n)来返回想要的数组

柯里化思想

柯里化部分求值,也就是延迟求值,等到需要的时候再求值
比如说要做累加,使用一个很简单的全局变量就可以实现,有一个专门的方法把传参加到全局变量上,但这样做当数据量很大时会很耗费资源,所以可以使用一个方法吧这些临时值先全部收集起来,等到我们想要实现运算的时候再取执行运算
比如说这样:

let collect = (() => {
    let arr = [];                     //做一个闭包来存储值
    return function () {
        if (arguments.length === 0) { //开始计算
            let count = 0;
            arr.forEach((v, k)=>{
                count += v;
            });
            return count;
            arr = null;              //无用释放
        } else {
            Array.prototype.push.apply(arr,arguments);
        }
    }
})();
collect(1);
collect(1);
collect(1.5);
console.log(collect());             //3.5

这不是一个真正柯里化,这段代码是为了帮助理解柯里化延迟计算的思想

柯里化实现

目标:把类似collect(1,2,3,4)的方法按collect(1)(2)(3)(4)方式执行,其实很像建造者模式, 在js里就相应的使用闭包来模拟私有变量存储这些参数
以下一段网上柯里化通用的方法

var curry = function (fn) {
    var _args = [];                  //存储参数待执行
    return function () {
        if (arguments.length === 0) {
            return fn.apply(this, _args);
        }
        Array.prototype.push.apply(_args, Array.prototype.slice.call(arguments));
        return arguments.callee;    //返回匿名函数
    }
};
var collect = function () {
    var total = 0;
    for (var i = 0, c; c = arguments[i++];) {
        total += c;
    }
    console.log(total);
}
var bulider =  curry(collect);     //来个类似builder的写法
bulider = bulider(1);
bulider = bulider(1,2);
bulider = bulider(3);
bulider();    //7
var collect2 = curry(collect);
collect2(1)(2)(3)(); //6

柯里化的好处

  1. 参数复用;
  2. 提前返回;
  3. 延迟计算/运行;

相关文章

  • js柯里化

    标签: js柯里化 js柯里化 柯里化是什么在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成...

  • [译]JavaScript中的函数柯里化

    原文 Currying in JS 函数柯里化 函数柯里化以Haskell Brooks Curry命名,柯里化是...

  • js柯里化

    在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函...

  • Js柯里化

    柯里化:函数接受一些参数,但不立即求值;返回一个匿名函数将参数保存下来;需要求值时将保存的全部参数一起用掉。(保存...

  • JS柯里化

    柯里化,即Currying,可以是函数变得更加灵活。我们可以一次性传入多个参数调用它;也可以只传入一部分参数来调用...

  • JS柯里化

    柯里化简介 js柯里化(currying)又译为卡瑞化或加里化,是把接受多个参数的函数,变为可接受多次调用的函数,...

  • JS柯里化

    前言 柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换...

  • js柯里化

    柯里化函数的实现hyCurrying

  • JS函数式编程之柯里化

    JS函数式编程之柯里化 为什么要了解柯里化 柯里化是函数式编程必须要使用的. 这里我们就先介绍下什么是柯里化, 然...

  • 前端 js 柯里化和反柯里化

    函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家H...

网友评论

    本文标题:JS柯里化

    本文链接:https://www.haomeiwen.com/subject/zvztsrtx.html