javascript-手写实现函数柯里化

loading 2022年11月22日 80次浏览

函数柯里化是指把多个参数的函数变换成接受一个单一参数的函数,一般通过闭包实现。

        function myCurry(fn, ...args) {
            // fn的参数个数
            let length = fn.length;
            // 真正要传入参数并执行的函数
            return function () {
                // 拼接旧数组和新传入参数 比如test(2,3)(4) 就是拼接[2,3]和[4]
                let newArgs = [...args , ...arguments];
                // 如果拼接后数组长度还未达到fn参数个数 说明参数还没传完 递归
                if (newArgs.length < length) {
                    return myCurry.call(this, fn, ...newArgs);
                // 参数传完了 调用函数
                } else {
                    return fn.apply(this, newArgs);
                }
            }
        }

        function fn(a,b,c){
            console.log(a*b*c);
        }
        let test = myCurry(fn);
        //传2,3时输出ok 最后输出24
        test(2)(3)(4);
        //传(2,3)时输出ok 最后输出24
        test(2,3)(4);
        //newArgs长度一次满足 不输出ok 直接输出24
        test(2,3,4);

上面这种手写可以应对大部分情况,除非fn的参数是不定长数组,此时length为0

        let fn = (...arr) => {};
        console.log(fn.length) // 0

会使得上面手写中的传参数量判断不准确,因此下面这种写法可能更能涵盖所有情况,缺点在于必须在最后加上一个空括号代表传参结束,比较好理解就不加注释了:

        // 手写函数柯里化
        const curring = function (fn) {
            const args = [];
            return function result(...rest) {
                if (rest.length === 0) {
                    return fn(...args)
                } else {
                    args.push(...rest);
                    return result;
                }
            }
        }
        const sum = (...arg) => {
            return arg.reduce((pre, cur) => {
                return pre + cur
            }, 0)
        }

        console.log(curring(sum)(1)(2, 5)(3)())