参考文章 Understanding Currying in JavaScript
译文 理解 JavaScript 的柯里化
首先柯里化是个什么?
百度的解释:
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数 (最初函数的第一个参数) 的函数,并且返回接受余下的参数且返回结果的新函数的技术。
// 现在有一个接受两个参数的函数 函数接受 3 个参数, 并返回 和
function fn1(param1, param2, param3) {console.log(param1 + param2 + param3)
}
fn1('a', 'b', 'c') // abc
// currying
function curryingfn1(param1) {return function (param2) {return function (param3) {return (param1 + param2 + param3)
}
}
}
curryingfn1('a')('b')('c') // abc
// 为了方便理解 可以依次执行
const _cfn1 = curryingfn1('a')
const _cfn2 = _cfn1('b')
const _cfn3 = _cfn2('c')
console.info({_cfn1, _cfn2, _cfn3})
得到的执行结果
这里的 fn1(‘a’, ‘b’, ‘c’)=> fn2(‘a’)(‘b’)(‘c’) 的过程就是 柯里化
附:使用箭头函数
fn3 = (param1) => (param2) => (param3) => console.log('fn3', param1 + param2 + param3)
fn3('a')('b')('c') // fn3 abc
以上,fn1 作为一个独立的函数已经被转换为一系列函数。
柯里化 能干什么呢?
// 参数复用
const regTest = (reg) => (text) => reg.test(text)
const checkNum = regTest(/\d+/g)
console.info(checkNum('aaa'), checkNum('123aaa')) //false true
附: 最近看到的一个面试题
// 实现方法
// fn(1) //1
// fn(1)(2) //5
// fn(1)(2)(3) //14
function curryingCount() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
var _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,利用闭包的特性保存_args 并收集所有的参数值
var _adder = function () {_args.push(...arguments);
return _adder;
};
// 利用 toString 隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = function () {return _args.reduce(function (a, b = 0) {return a + b * b;});
}
_adder.value = _adder
return _adder;
}
// 或者使用箭头函数!!注意~~~~, 箭头函数没有 this 和 arguments
curryingCount2 = (...arguments) => {
// 第一次执行时,定义一个数组专门用来存储所有的参数
const _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,arguments 作为参数传递值
const _adder = (...arguments) => {_args.push(...arguments);
return _adder;
};
// 利用 toString 隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = () => _args.reduce((a, b = 0) => a + b * b);
return _adder;
}