利用柯里化和闭包--实现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));

打印结果

总结

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

相关推荐
天平43 分钟前
油猴脚本创建webworker踩坑记录
前端·javascript·typescript
原则猫2 小时前
前端基础大厦
前端
陈随易3 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·后端·程序员
SoaringHeart4 小时前
Flutter进阶:基于 EasyRefresh 的下拉刷新封装 n_easy_refresh_mixin.dart
前端·flutter
IT_陈寒6 小时前
Vite的热更新突然不香了,排查三小时差点砸键盘
前端·人工智能·后端
子兮曰6 小时前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding
山河木马7 小时前
渲染管线-计算得到gl_Position(顶点着色器)之后续GPU流程
javascript·webgl·图形学
竹林8187 小时前
用 The Graph 查询链上数据实战:从手搓 RPC 到 Subgraph,我的 NFT 项目数据加载快了 10 倍
前端·javascript
妙码生花7 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
Awu12278 小时前
⚡从零开发 Agent CLI(五)实现一个可治理、可扩展的工具系统
前端·人工智能·claude