侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

JS柯里化

2024-05-07 星期二 / 0 评论 / 0 点赞 / 55 阅读 / 3370 字

在做项目的过程中,遇到一个业务需求,需要用到柯里化。 接着回过头看看什么是柯里化。抄一段百度百科的解释: 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最

在做项目的过程中,遇到一个业务需求,需要用到柯里化。

接着回过头看看什么是柯里化。抄一段百度百科的解释:

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

对于我们的关注点来说,重要的不是它是什么,而是它能为我们做什么。柯里化有三个常见的作用:1.参数复用,2.提前返回,3.延迟计算/运行。这里我们要用到它的第三个作用,延迟计算。

这里看一个例子:

//Curry var curry = function(fn) {    var args = [].slice.call(arguments, 1);  //等同于arguments.slice(1);    return function() {        // 将新参数和之前的参数连接起来作为curry函数中所传入函数的参数。        var newArgs = args.concat([].slice.call(arguments));        return fn.apply(null, newArgs);    };}var add = function(x,y) {    return x + y;}// 调用curry函数,传入一个add方法和一个参数5,此时这里的5等于上面的args。var result = curry(add, 5)// 当调用result函数并传入参数 10 时,// 将10和之前的参数5结合起来作为之前curry函数中add方法的两个参数,// 并运行执行,最终返回10。console.log(result(10)); //15

在这里,当我们调用curry函数时,将5作为curry函数中add方法的第一个参数,并保存起来,(这里用到了闭包的知识,所以能保存,闭包以后再谈,因为现在不会-_-!)然后在下面调用result方法并传入参数10,此时参数 10 作为add方法的第二个参数传入,并执行。最终返回结果:15。
当我们调用result方法时,不需要再显示的传入第一个参数,只需要传入第二个参数即可完成方法调用。

接下来,我们人工debug一下这段代码。在curry函数中,至少需要接受一个参数 fn,然后进入 var args = [].slice.call(arguments, 1); 这里将在调用curry函数中,可能传入的后续参数保存为数组args。在curry函数return的function 中,这里的function就是result。在return的函数中,将新传入的参数与原来的args数组合并为新的参数数组newArgs,并最终传给fn,作为fn 的参数。此时就完成了参数的合并。

接着跑一下这段代码,var result = curry(add, 5); 这里传入的参数5,被放到了args里面保存起来等待与新的参数合并。 最后执行 result(10),10 作为curry函数中,renturn function 里面的新传入的参数,与之前的args里的5合并成为[5,10],然后fn.apply(null, newArgs),新参数传给fn,也就是这个add函数,调用add,最终返回结果 15.

写的有些乱,有看不懂的地方可以提出来再修改下。当然,curry还有另一种写法curryRight.

function curryRight(fn) {    var args = [].slice.call(arguments, arguments.length - 1);    return function() {        var newArgs = [].concat([].slice.call(arguments), args);        return fn.apply(null, newArgs);    };}

大同小异,自己体会。

广告 广告

评论区