函数的柯里化及封装

69 阅读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(/^\w{6,8}$/, 'qwer')
         testStr(/^\d{5,8}$/, '12345')
         testStr(/^\d{5,8}$/, '54321')
         testStr(/^\d{5,8}$/, '124567890')
         testStr(/^\d{5,8}$/, '98765')
         testStr(/^\d{5,8}$/, 'qwertyui')

        /**
         *  柯里化函数:
         *      一个函数接收多个参数能够完成功能, 柯里化函数就是将这一个函数拆分为两个函数
         *      每个函数都只接受一个参数, 然后完成的功能相同
        */
        function fn(fnReg) { // 外层函数, 负责接收正则
            return function (fnStr) {    // 内层函数, 负责接收字符串, 并完成正则校验
                // console.log(fnReg.test(fnStr))   // 只有 console.log 才会向控制台打印内容
                return fnReg.test(fnStr)    // 将校验结果返回出去给外部代码使用
            }
        }

        const testNum = fn(/^\d{5,8}$/)
        testNum('1234')
        testNum('4321')
        testNum('123')

        const testName = fn(/^\w{6,12}$/)
        testName('qwertyui')
        testName('kjhgfdsa')

函数的柯里化封装

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

     *      功能: 拼接地址栏字符串

     *      https://www.baidu.com/index.html
     *      https://www.baidu.com/a.html

     *          传输协议: 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
         }
         fn('http', '127.10.11.12', '8080', '/index.html')
         fn('http', '127.10.11.12', '7777', '/index.html')
         fn('http', '127.10.11.12', '7777', '/a.html')
         fn('http', '127.10.11.12', '7777', '/b.html')
         fn('http', '127.10.11.12', '7777', '/c.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 ('当前接收参数的数量' === '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())

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