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

打印结果

总结

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

相关推荐
华玥作者13 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
Mr Xu_14 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠14 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
sleeppingfrog14 小时前
zebra通过zpl语言实现中文打印(二)
javascript
lang2015092814 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
好家伙VCC15 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
未来之窗软件服务15 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
baidu_2474386115 小时前
Android ViewModel定时任务
android·开发语言·javascript
嘿起屁儿整16 小时前
面试点(网络层面)
前端·网络
VT.馒头16 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript