函数的柯里化

11 阅读1分钟

需求:使用正则完成一个文本匹配

    // 基础版
    // const reg = /^\w{6,12}$/
    // const str = '12345'
    // console.log(reg.test(str))
    // 优化
    // function testStr(fnReg, fnStr) {
    //   const reg = fnReg
    //   const str = fnStr
    //   console.log(reg.test(str))
    // }
    // testStr(/^\d{5,8}$/, '12345')
    // testStr(/^\w{6,8}$/, 'qwerty')

柯里化函数

  • 一个函数接收多个参数能够完成功能,柯里化函数就是将这一个函数拆分为两个函数
  • 每个函数都只能接受一个参数,然后完成的功能相同
    function fn(fnReg) { //外层函数,负责接收正则
      return function(fnStr) { //内层函数,负责接收字符串,并完成正则校验
        // console.log(fnReg.test(fnStr))
        return fnReg.test(fnStr) //将校验结果返回出去给外部代码使用
      }
    }
    const testNum = fn(/^\d{5,8}$/)
    // console.log(testNum)
    testNum('1234') //false

函数的柯里化封装

  • 函数柯里化内
    • 外层函数: 收集参数
    • 内层函数: 负责处理功能
  • 功能: 拼接地址栏字符串
    • 传输协议: http https
    • 域名: 127.0.0.1 localhost
    • 端口号: 0~65535 7777 8080 8081
    • 地址: /a /a/b.html /index.html
    // 普通版
    // function fn(a, b, c, d) {
    //   return a + '://' + b+ ':' + c + d
    // }
    // console.log(fn('http', '127.0.0.1', '8080', '/index.html'))
    // 柯里化版
    function fn(a, b, c, d) {
      return a + '://' + b + ':' + c + d
    }
    function curry(callback, ...arg) { //外层函数:负责接收参数
      // console.log("callback", callback)
      // console.log('arg', arg)
      /**
       * curry  函数需要接受两个参数,
       *    callback: 当参数传递足够时需要执行的函数
       *    ...arg: 接受后续这个参数传递所有实参(以数组的形式存储)
       * */ 
      return function(..._arg) { //内层函数: 负责处理功能
        _arg = [...arg, ..._arg] //把所有参数放在一个数组中,方便统一维护与管理
        // if('当前接收参数的数量' === 'fn函数需要的参数数量') { 函数名.length => 就是这个函数形参的数量
        //   '执行fn函数'
        // }else {
        //   '此时参数数量不满足函数要求,需要继续收集参数'
        // }
        if(_arg.length === callback.length) {
          return callback(..._arg)
        } else {
          return curry(callback, ..._arg)
        }
      }
    }
    // let newFn = curry(fn, 'http', '127.0.0.1', '8080', '/index.html')
    // console.log(newFn())

    const newFn = curry(fn)
    const newFn2 = newFn('https')
    const newFn3 = newFn2('127.0.0.1')
    const newFn4 = newFn3('8080')
    const newFn5 = newFn4('/index.html')
    console.log(newFn5)