函数柯里化
在函数式编程中,函数柯里化是指将接受多个参数的函数转为接受不定个数参数的高阶函数。
从功能上说,它实现了函数功能的细化。
1. 背景基础知识
1)函数的length属性--返回定义时的函数参数个数
es6中,函数参数可以设置默认值,length属性指的是未设置默认值的参数个数,设置了默认值的参数后面的都不算。
length属性也不包含rest参数。
// 应用:可以用来判断函数定义时和调用时的参数差异 function test(a,b,v) { // ... } test(1,2,3,4,5) console.log(test.length) // 3 // 实际参数长度5,定义时参数长度为3 function sum(a, b=6, c){} console.log(sum.length); // 1
2) 函数参数的剩余运算符...和扩展运算符
当参数的个数不确定时,使用剩余运算符。
function do(...args) { console.log(args); // 参数组成的数组 } do(1,2,3,4); // [1,2,3,4] do(1,2,3); //[1,2,3]
2. 实现函数柯里化
实现原则:
1. 收集参数
2. 参数收集完成后,返回原函数的执行结果
function curry(fn, arr=[]) { const length = fn.length; return function(...args) { arr = arr.concat(args); // 柯里化后参数总数和原函数相同 if (arr.length < length) { return curry(fn, arr) } } }
测试用例:
function add(a,b,c,d,e) { return a+b+c+d+e; } // 原函数调用 console.log(add(1,2,3,4,5)) ; // 等同于 console.log(curry(add)(1,2,3)(4,5)) console.log(curry(add)(1,2)(3)(4,5)) //参数可以任意组合
应用:
实现数据的类型检查
function checkType(type, data) { return Object.prototype.toString.call(data) === `[object ${type}]` } let isString = curry(checkType)('String'); //检查是否是字符串的函数 console.log(isString('ddd'));
3. 优缺点:
1.优点:
1)可以实现参数复用
2)实现延迟执行;先收集所有参数,最后执行
3)实现功能细化
2. 缺点:
1. 实现出现闭包,占用大量内存,产生性能问题
2. 递归效率低