函数柯里化

2023-05-28 16:32:05 浏览数 (2)

一、定义

把一个接受多个参数的函数变为接受一个参数的函数,同时返回剩余参数且返回结果的新函数

二、应用

提取公共柯里化函数,接受至少两个参数,一个是处理函数,其余参数是处理函数所需的参数,以下代码为校验的方法

代码语言:javascript复制
import { singleton } from "./singleton";

class Common {
    currie() {
        const fn = arguments[0];
        const args = Array.prototype.slice.call(arguments, 1);
        if (args.length === fn.length) {
            return fn.apply(null, args);
        }
        const _currie = function () {
            args.push(...arguments);
            if (args.length === fn.length) {
                return fn.apply(null, args);
            }
            return _currie;
        }
        return _currie;
    }
    verify(reg, txt) {
        return reg.test(txt);
    }
    isPhoneNumber(tel) {
        const reg = /^0?1[3|4|5|6|7|8][0-9]d{8}$/;
        return this.currie(this.verify, reg)(tel);
    }
}

export default singleton(Common);

三、性能

a. 因要修改this指向等,使用apply,比直接调用fn稍慢些

b. 需要使用到闭包,内存开销相对较大,最好在执行完毕手动释放内存

c. 读取arguments往往比直接读取命名参数要稍微慢,尤其老版本浏览器则很明显

四、面试真题

实现以下这么sum函数,满足一下需求

代码语言:javascript复制
sum(1, 2) == 3
sum(1)(2) == 3
sum(1)(2, 3) == 6
sum(1)(2)(3)(4) == 10

分析如下: 1. 参数数量不一,考虑使用闭包存储每次的参数

2. 支持链式调用,需返回function 3. 最终输出结果,可以考虑拦截Function的toString或者valueOf

代码如下:

代码语言:javascript复制
function sum() {
    const _args = Array.prototype.slice.call(arguments);
    const _sum = function() {
        _args.push(...arguments);
        return _sum;
    }
    _sum.toString = function() {
        return _args.reduce((a, b) => {
            return a   b;
        })
    }
    // _sum.valueOf = function() {
    //     return _args.reduce((a, b) => {
    //         return a   b;
    //     })
    // }
    return _sum;
}

0 人点赞