什么是js函数的currying/柯里化
说道js的柯里化,相信很多朋友都会头大,或者不是很清楚。用一句话总结柯里化,js柯里化是逐步传值,逐步缩小函数的适用范围,逐步求解的过程。
可能对这句话你不是很清楚,那么我们来看个案例,简单说明一下:
需求:我们写一个函数,将函数的几个参数相加,返回结果!那么我们写的函数如下:
![img_ddb2fccae41585273a1d334c1f6f4e65.png](https://yqfile.alicdn.com/img_ddb2fccae41585273a1d334c1f6f4e65.png?x-oss-process=image/resize,w_1400/format,webp)
函数柯里化呢?是分部求解,先传一个a参数,再传一个b参数,再传一个c参数,最后将这三个参数相加!
![img_d93635100bd7addf0d34a9661585c004.png](https://yqfile.alicdn.com/img_d93635100bd7addf0d34a9661585c004.png?x-oss-process=image/resize,w_1400/format,webp)
我们看输出结果:
![img_5ddb3df775b411f6aa9183f000dbd63d.png](https://yqfile.alicdn.com/img_5ddb3df775b411f6aa9183f000dbd63d.png?x-oss-process=image/resize,w_1400/format,webp)
柯里化案例
上面的需求我们稍微改变一下。现在我们更进一步,如果要求可传递的参数不止3个,可以传任意多个参数,当不传参数时输出结果?那我们现在用柯里化简单实现一下:
![img_e6cba641234565b60ddd0d3935d07544.png](https://yqfile.alicdn.com/img_e6cba641234565b60ddd0d3935d07544.png?x-oss-process=image/resize,w_1400/format,webp)
上面adder是柯里化了的函数,它返回一个新的函数,新的函数接收可分批次接受新的参数,延迟到最后一次计算,我们可以任意传入参数,当不传参数的时候,输出计算结果!
基础知识普及之arguments
arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性,arguments非常类似Array,但实际上又不是一个Array实例。
![img_0e3f83724ea5bbf1ed5367e72c802dc8.png](https://yqfile.alicdn.com/img_0e3f83724ea5bbf1ed5367e72c802dc8.png?x-oss-process=image/resize,w_1400/format,webp)
我们通常用 [].slice.call(arguments,1)
将传入参数转为数组。slice是js的一个函数,上面的写法相当于Array.prototype.slice.call(arguments,1)
另外,arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。
基础知识普及之reduce()方法
通用的柯里化函数
下面这个是通用的柯里化函数:
![img_15203bb17b6f064f95a089455e8fcfa5.png](https://yqfile.alicdn.com/img_15203bb17b6f064f95a089455e8fcfa5.png?x-oss-process=image/resize,w_1400/format,webp)
我们可以通过如下函数简单应用一下柯里化:
![img_2ac37b87a6e32067a8712c795d2f0c9f.png](https://yqfile.alicdn.com/img_2ac37b87a6e32067a8712c795d2f0c9f.png?x-oss-process=image/resize,w_1400/format,webp)
增加适用性的柯里化
还有一种是增加了函数的适用性,但同时也降低了函数的适用范围。其通用写法如下:
![img_be68691db3c8bf307fe8786d272808e9.png](https://yqfile.alicdn.com/img_be68691db3c8bf307fe8786d272808e9.png?x-oss-process=image/resize,w_1400/format,webp)
例如:
![img_84b0830a5919283721ddd39b3502bc5f.png](https://yqfile.alicdn.com/img_84b0830a5919283721ddd39b3502bc5f.png?x-oss-process=image/resize,w_1400/format,webp)
例子中,创建了map通用函数,用于适应不同的应用场景。显然,通用性不用怀疑。同时,例子中重复传入例如相同的处理函数:square
柯里化改造:
![img_77f6a25f949fbf7263a7c14e30086e11.png](https://yqfile.alicdn.com/img_77f6a25f949fbf7263a7c14e30086e11.png?x-oss-process=image/resize,w_1400/format,webp)
Function.prototype.bind方法也是柯里化应用
与call/apply方法直接执行不同,bind方法将第一个参数设置为函数执行上下文,其他参数一次传递给调用方法(函数的主题本身不执行,可以看成是延迟执行),并动态创建返回一个新的函数,这符合柯里化特点
![img_6de11dcd83ede9854838dd0bdfa3163b.png](https://yqfile.alicdn.com/img_6de11dcd83ede9854838dd0bdfa3163b.png?x-oss-process=image/resize,w_1400/format,webp)
关于函数柯里化就说到这里。