浅识js —— 函数的柯里化

57 阅读1分钟

js基础知识——函数的柯里化

一、柯里化?

  • 一个函数接收多个参数能够完成功能, 柯里化函数就是将这一个函数拆分为两个函数
  • 每个函数都只接受一个参数, 然后完成的功能相同

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

     // 基础版
        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(/^\w{6,12}$/,'12456')
    testStr(/^\w{6,12}$/,'987551')
    testStr(/^\w{6,12}$/,'12599')
    testStr(/^\w{6,12}$/,'48814898')
    // 函数的柯里化方式!
     function fn(fnReg){ //外层函数,负责接收正则
        return function (fnStr){  //内层函数负责接受字符串,并完成正则校验
          console.log(fnReg.test(fnStr))
          return fnReg.test(fnStr)     //test匹配字符串是否符合正则规则

        }
      }
    
      const testNum = fn(/^\d{6,12}$/)
      testNum('123654')
      testNum('965214857')
      testNum('6665')
      const testName = fn(/^\w{5,8}$/)
      testName('aasdffg')
      testName('@##¥')

二、函数的柯里化封装

  • 函数柯里化内
    • 外层函数:收集参数
    • 内层函数:负责处理功能

需求/功能:拼接地址栏字符串

  • 传输协议: http https
  • 域名: 127.0.0.1 localhost
  • 端口号: 0~65535
  • 地址:/a /a/b.html /index.html
     // 普通版
    function fn(a,b,c,d){
      return a + '://' + b + ':' + c + d
    }
    fn('http','127.10.11.12','8808','/index.html')
    console.log( fn('http','127.10.11.12','8808','/index.html'))
       // 柯里化版
        function fn(a, b, c, d) {
            return a + '://' + b + ':' + c + d
        }

        function curry(callback, ...arg) {  // 外层函数: 负责接收参数
            /*
             *  curry 函数 需要接受两个参数
             *      callback: 当参数传递足够时需要执行的函数
             *      ...arg: 接收后续这个参数传递所有实参 (以数组的形式存储)
            */

            return function (..._arg) {    // 内层函数: 负责处理功能
                _arg = [...arg, ..._arg]    // 把所有参数放在一个数组中, 方便统一维护与管理

                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())

          let newFn = curry(fn, 'http')
          const newFn2 = newFn('127.0.0.1', '8080')
          const newFn3 = newFn2('/index.html')
          console.log(newFn3)

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