函数柯里化
什么是函数柯里化?
百度百科:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。通俗点说就是将一个函数拆分成多个函数,是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。来个简单的例子
1 // 实现一个简单的加法 2 function add(a,b){return a+b} 3 add(1,2); 4 // 用柯里化实现 5 const currying = (x) => { 6 return (y) => {return x+y} 7 } 8 console.log(currying(1)(2)) // 3
这里就是使用柯里化把add函数拆分成了两个函数,currying首次执行返回一个新的函数,然后再次调用返回结构,返回一个函数的特征就是上一章所说到的高阶函数,柯里化函数就是高阶函数的一种。这里就会有人提问了,为什么要那么费劲实现add函数?有道经典的面试题实现add(1)(2)(3)(4)=10;
1 // 我们可以这样理解调用add(1)时返回一个函数fn,然后执行fn(2)依次被调用,当执行到最后一次返回结果 2 function add(num){ 3 var sum=num; 4 var fn=function(v){ 5 sum+=v; 6 return fn 7 }; 8 fn.toString=function(){ 9 return sum 10 }; 11 return fn 12 } 13 console.log(add(1)(2)(3)(4)) // 10 14 // 执行add(1)时返回了fn函数给2,3,4执行,同时定义了fn的toString方法, 15 // 每个对象的toString和valueOf方法都可以被改写,每个对象执行完毕,如果被用以操作JavaScript解析器就会自动调用对象的toString或者valueOf方法 16 // 利用toString隐式调用的特性,当最后执行时隐式调用,并计算最终的值返回
面试题的内容还有 add(1)(1,2,3)(2)=9 这样的形式,我们上面的方法就没办法执行出正确的答案了,下面来优化一下
1 function add(){ 2 var args = [...arguments]; 3 var fn=function(){ 4 args.push(...arguments); 5 return fn 6 }; 7 fn.toString=function(){ 8 return args.reduce(function (a, b) { 9 return a + b; 10 }); 11 }; 12 return fn 13 } 14 console.log(add(1)(1,2,3)(2).toString())
以上就是函数柯里化的简单实现。继续来实现一些例子来看看柯里化的好处
1 // 实现一个判断数据类型的方法 2 const checktype = function(type, content) { 3 return Object.prototype.toString.call(content) === `[object ${type}]`; 4 } 5 checktype('Number',2); // true 6 // 这种方法总是要把type参数传过去,如果写错了就会影响到正确的结果了,可以考虑下如何做到把“Number“做到复用 7 8 const curry = function(type){ 9 return function(content){ 10 return Object.prototype.toString.call(content) === `[object ${type}]`; 11 } 12 } 13 const isNumber = curry('Number'); 14 isNumber(3) // true 15 // 这里就实现参数的复用了,这样的实现给之后的调用带来了很大的便利