利用柯里化和闭包--实现add函数

前言

什么是柯里化?

柯里化就是将一个接收多个参数的函数,转化为多个函数,每个函数都只接收一个参数并返回一个新的函数,直到所有参数都被提供完毕。

示例

手写一个 add 函数实现两数相加

javascript 复制代码
function add(a, b) {
    if(arguments.length < 2) {
        console.log('参数不足');
        return
    }
    // 数据类型, 参数数量的问题
    if(typeof a != 'number' || typeof b != 'number') {
        console.log('类型错误');
        return
    }
    return a + b;
}

console.log(add(1, 2));
console.log(add(1, '2'));
console.log(add(1));

打印结果

还可利用闭包完成一个add,实现分布接收参数,一次只接收一个参数

javascript 复制代码
function add(a) {
    // 第一个参数a
    return function(b) {
        return a + b;
    }
}

console.log(add(2)(4));

打印结果

分析

add函数执行完成后,会返回一个匿名函数function,function执行完要返回 a + b的值,由于a是add函数的值,function要用到a的值,所以add在执行完毕后会生成一个闭包里面存放了a的值,function会在这个闭包里寻找a的值,最后做加法运算并返回值。

如果参数不定,该如何实现?

对于es5,函数内置了一个arguments对象,它包含了传给该函数的所有参数,可以通过arguments[i]来访问这些参数。

javascript 复制代码
const curry = function (fn) {
    // 参数对象
    for (let i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}
function add(x, y, z, m) {
    return x + y + z + m;
}

curry(add, 1, 2, 3)

打印结果

对于es6,为了让代码更加简洁,引入了 ...args rest运算符,其能够接收任意数量的参数,并将它们以数组的形式收集起来。

javascript 复制代码
const curry = (fn, ...args) => {
    console.log(args);
}
function add(x, y, z, m) {
    return x + y + z + m;
}

curry(add, 1, 2, 3)

打印结果

注: 如果使用了箭头函数 arrow function ,又去使用了es5 里面的arguments,由于箭头函数里面没有arguments,违反了es6 简洁的原则,所以应该用rest 运算符

柯里化的思路:

定义一个curry函数,用于将add函数需要的参数逐个传入,并且需要一个判断语句 args.length >= fn.length ? fn(...args) :(..._args) => curry(fn, ...args, ..._args),如果传入的参数大于或者等于fn所需要的参数个数,则执行fn(...args),将...args所接收到的所有参数传给fn;否则,执行(..._args) => curry(fn, ...args, ..._args),返回一个新的柯里化函数,..._args继续接收参数,并且将已有的参数...args与新参数进行合并,再递归调用curry函数,直到接收到的参数足够调用fn。

php 复制代码
const curry = (fn, ...args) => 
    args.length >= fn.length
    ? fn(...args)
    :(..._args) => curry(fn, ...args, ..._args)

// 原函数
// 柯里化,慢慢收集参数
const add = (x, y, z, m) => {
    return x + y + z + m
}

console.log(curry(add, 1)(2)(3)(4));

打印结果

总结

快去自己手搓一个柯里化函数,实现逐个传参。

相关推荐
文心快码BaiduComate7 分钟前
WAVE SUMMIT深度学习开发者大会2025举行 文心大模型X1.1发布
前端·后端·程序员
babytiger8 分钟前
python 通过selenium调用chrome浏览器
前端·chrome
passer98114 分钟前
基于webpack的场景解决
前端·webpack
华科云商xiao徐21 分钟前
Java并发编程常见“坑”与填坑指南
javascript·数据库·爬虫
奶昔不会射手27 分钟前
css3之grid布局
前端·css·css3
举个栗子dhy31 分钟前
解决在父元素上同时使用 onMouseEnter和 onMouseLeave时导致下拉菜单无法正常展开或者提前收起问题
前端·javascript·react.js
Coding_Doggy37 分钟前
苍穹外卖前端Day1 | vue基础、Axios、路由vue-router、状态管理vuex、TypeScript
前端
前端与小赵38 分钟前
vue3和vue2生命周期的区别
前端·javascript·vue.js