一、什么是函数柯里化
函数柯里化,最早接触他是因为bind函数,bind函数内部会在返回一个函数,供我们再调用。什么是柯里化呢?
函数柯里化指的是如果之前函数有多个参数,将函数变成一系列接收一个参数的函数。好难懂~~
二、函数柯里化有啥用
2.1 参数复用
//下面是一个正则的校验,正常来说直接调用check函数就可以了,
//但是如果我有很多地方都要校验是否有数字,
//其实就是需要将第一个参数reg进行复用,
//这样别的地方就能够直接调用hasNumber,hasLetter等函数,
//让参数能够复用,调用起来也更方便。
// 正常正则验证字符串 reg.test(txt)
// 函数封装后
function check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test') //false
check(/[a-z]+/g, 'test') //true
// Currying后
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)
hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
2.2 延迟调用
就是bind()函数的用法啦,会返回一个函数,不会立即执行
//像我们js中经常使用的bind,实现的机制就是Currying.
Function.prototype.bind = function (context) {
var _this = this
var args = Array.prototype.slice.call(arguments, 1)
return function() {
var _args = [...args,...arguments]
return _this.apply(context, _args)
}
}
三、手写实现柯里化
// 函数参数给定
function curry1(fn,...args){
return function(){
var _args = [...args,...arguments]
if(fn.length > _args.length){
return curry1(fn,..._args)
}
return fn.apply(null,_args)
}
}
// 函数参数个数不定
function curry(fn,...args){
var f = function(){
var _args = [...args,...arguments]
return curry(fn,..._args)
}
f.toString = function(){
return fn.apply(null,args)
}
return f
}
function add(a,b,c){
console.log(a-b-c)
}
var a = curry(add)
a(1,2)(3).toString()
a(1)(2)(3).toString()
var a1 = curry1(add)
a1(1,2)(3)
a1(1)(2)(3)
四、面试代码
要求实现sum(1,2,3)(4).toString() = 10;sum(1,2)(3).toString() = 6
function sum(...args){
var f = function(){
var _args = [...args,...arguments]
return sum(..._args)
}
f.toString = function(){
console.log(args.reduce((a,b)=>a+b))
}
return f
}
sum(1,2,3)(4).toString() //10
sum(1)(2)(3).toString() //6