热搜:m1 nginx 代理 前端

前端开发中的函数柯里化(原创)

2024-03-31 02:16:41

柯里化(currying)是把接受多个参数的函数变换成接受一个参数的函数,并且返回接受剩余参数且返回结果的新函数的技术。

柯里化后的函数接收参数的数量与原函数的形参数量相等时,执行原函数;当接收的参数数量小于原函数形参数量时,返回一个用于接收剩余参数的函数。

前端开发中的函数柯里化(原创) 1

// 1 只能传被柯里化函数形参的个数,多少都不行
function currying(fn, ...args) {
    const length = fn.length;
    return function(...newArgs) {
        const allArgs = [...args, ...newArgs];
        if (allArgs.length < length) {
            return currying.call(this, fn, ...allArgs);
        } else {
            return fn.apply(this, allArgs);
        }
    }
}
const add = (a, b, c) => a + b + c;
const addCurrying = currying(add);
console.log(addCurrying(1)(2)(3));
console.log(addCurrying(1,2)(3));
console.log(addCurrying(1)(2,3));
console.log(addCurrying(1,2,3));

// 2 参数长度不固定,最后需要手动调用一次
function currying(fn, ...args) {
    let allArgs = [...args];
    return function temp(...newArgs) {
        if (newArgs.length) {
            allArgs = [...allArgs, ...newArgs];
            return temp;
        } else {
            const res = fn.apply(this, allArgs);
            allArgs = [...args];
            return res;
        }
    }
}
const add = (...args) => args.reduce((a, b) => a + b);
const addCurrying = currying(add);
console.log(addCurrying(1)(2)(3)(4,5)());
console.log(addCurrying(1)(2)(3,4,5)());
console.log(addCurrying(1)(2,3,4,5)());

柯里化用途

// 1 校验规则
// 原函数
function checkByRegExp(regExp, string) {
    return regExp.test(string);  
}
// 普通使用
checkByRegExp(/^1d{10}$/, '18642838455'); // 校验电话号码
checkByRegExp(/^(w)+(.w+)*@(w)+((.w+)+)$/, 'test@163.com'); // 校验邮箱
// 柯里化后使用
let check = currying(checkByRegExp);
let checkCellPhone = check(/^1d{10}$/);
let checkEmail = check(/^(w)+(.w+)*@(w)+((.w+)+)$/);
checkCellPhone('18642838455'); // 校验电话号码
checkCellPhone('13109840560'); // 校验电话号码
checkCellPhone('13204061212'); // 校验电话号码
checkEmail('test@163.com'); // 校验邮箱
checkEmail('test@qq.com'); // 校验邮箱
checkEmail('test@gmail.com'); // 校验邮箱
// 2 提取对象数组的某一属性
const list = [
    {name:'lucy'},
    {name:'jack'}
];
// 普通使用
const names = list.map(item => item.name);
// 柯里化使用
const prop = currying((key, obj) => obj[key]);
const names = list.map(prop('name'));