js函数柯里化

·  阅读 350

函数柯里化(Currying) 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

高阶函数:
  • 回调函数:一个函数的参数是一个参数
  • 函数柯里化:一个函数返回一个函数
//普通的函数
function add(x, y) {
    return x + y
}
add(1, 2)   //3

//柯里化后的函数
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}
curryingAdd(1)(2)   //3
复制代码

函数柯里化的实现

函数柯里化 是将原来接受两个参数的函数变成新的接受一个参数的函数的过程,新的函数返回一个以原有第二个参数为参数的函数,这些函数不会立即求值,而是通过闭包的方式把传入的参数保存起来,直到真正需要的时候才会求值,减少了代码的冗余,实现函数的复用,是 js 函数式编程的一项重要应用

  • 柯里化不会调用函数,只是对函数进行转换
  • 柯里化是一种函数的转换,指将一个函数从可调用的 fn(x, y, z, ...) 转换为可调用的 fn(x)(y)(z)...
//正则表达式匹配验证函数
//普通的函数
function checkText(reg, text) {
    return reg.test(text)
}
//匹配数字
checkText(/\d+/g, 123)   //true
checkText(/\d+/g, 'abc')   //false
//匹配字母
checkText(/[a-z]+/g, 123)   //false
checkText(/[a-z]+/g, 'abc')   //true

//柯里化后的函数
function curryingCheckText(reg) {
    return function(text) {
        return reg.test(text)
    }
}
//匹配数字函数
let isNumber = curryingCheckText(/\d+/g)
//匹配字母函数
let isLetter = curryingCheckText(/[a-z]+/g)
//实现匹配函数复用
isNumber(123)   //true
isNumber('abc')   //false
isLetter(123)   //false
isLetter('abc')   //true
复制代码
使用 Lodash.js 工具库的 _.curry 方法
//引入lodash工具库
<script src="https://cdn.bootcdn.net/ajax/libs/lodash-fp/0.10.4/lodash-fp.js"></script>
<script>
    function sum(a, b, c) {
        return a + b + c
    }
    //使用lodash工具库的_.curry方法实现柯里化函数
    let currySum = _.curry(sum)
    
    console.log(currySum(1, 2, 3))   //6
    console.log(currySum(1, 2)(3))   //6
    console.log(currySum(1)(2)(3))   //6
</script>
复制代码
创建函数柯里化辅助函数

创建一个函数柯里化辅助函数 _curry(func),该函数将对接收多个参数的函数 func 执行柯里化

  • 对于多个参数的函数 func(x, y, z, ...) 执行 _curry(f) 会将其转换为可以以 func(x)(y)... 形式运行的函数
//创建一个函数柯里化辅助函数_curry()
function _curry(func) {
    return function curry(...args1) {
        if (args1.length >= func.length) {
            return func.apply(this, args1)
        } else {
            return function(...args2) {
                return curry.apply(this, args1.concat(args2))
            }
        }
    }
}

function sum(a, b, c) {
    return a + b + c
}
//使用_curry()函数实现柯里化函数
let currySum = _curry(sum)

console.log(currySum(1, 2, 3))   //6
console.log(currySum(1, 2)(3))   //6
console.log(currySum(1)(2)(3))   //6
复制代码
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改