函数柯里化——小心一点炫技

看到柯里化(Currying),我相信爱好篮球的程序员一定会想到斯蒂芬·库里(Stephen Curry),常常投出不讲理的三分,让对手和队友目瞪口呆。函数柯里化也要讲究"得分效率"哦,在使用它时,应该考虑可读性与维护性,不要一不小心多炫啦。

函数柯里化


一、概念

定义: 它是将多参数函数转化为一系列单参数函数的技术,以逻辑学家Haskell Curry名字命名。

核心思想:将一个接受多个参数的函数转化为一系列链式函数调用,每个函数接受原函数的一个参数,并返回一个新的函数,直到所有参数都被接收为止。

二、为什么能实现?

一等公民的函数: 在JavaScript中,函数可以像变量一样被赋值给变量,作为参数传递给其他函数,或者从函数中返回。这是实现柯里化的基础。

闭包: 闭包允许一个函数访问并操作其外部作用域中的变量。在柯里化中,每次返回的新函数都会形成一个闭包,保持对外部函数中变量的引用,以便在后续调用中继续使用。

不定参数列表: 在箭头函数中使用 ...args 可以捕获所有传入的参数作为一个数组,这使得函数可以接受任意数量的参数,非常适用于实现柯里化求和这样的功能。

三、arguments与rest参数

arguments:

  • 函数运行时参数管理对象 --> 类数组对象
  • Object.prototype.toString.call(arguments) ==[object Arguments]
  • 具有for .length的能力,但是forEach,join reduce等方法是没有的。
javascript 复制代码
function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}
console.log(sum(1, 2, 3, 4),Object.prototype.toString.call(arguments));

rest参数

  • 从ES6开始,JavaScript引入了rest参数语法,它允许你在一个函数中收集不定数量的参数到一个数组中。
  • rest参数必须是函数参数列表中的最后一个参数。

现代JavaScript倾向于使用rest参数而不是 arguments,因为它提供了更好的语义清晰度和更丰富的数组操作能力。

javascript 复制代码
function sum(...numbers) {
    return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 输出:10

四、柯里化

  • add()函数实现一个简单的函数柯里化
javascript 复制代码
function add(x) {
    return function(y) {
        return x + y;
    };
}

const add5 = add(5); 
console.log(add5(3)); // 输出 8

add(5)的执行结果返回新函数add5后,add5在接受参数3,add5(3)的执行结果输出8。

在实际的应用中,它可以用于创建更加灵活和可重用的函数。例如,在一个需要多个参数的复杂函数中,可能在不同情况下只要设置某些参数,而其他的参数保持未确定的状态。通过柯里化,你可以创建一个函数家族,每个函数都针对特定场景进行了优化。

  • 更复杂的函数柯里化----接受任意参数并求和。
ini 复制代码
const curryAdd = (...args) => {
    let total = args.reduce((acc, val) => acc + val, 0);

    const foo = (...moreArgs) => {
        if (moreArgs.length > 0) {
            return curryAdd(...args, ...moreArgs);
        } else {
            return total;
        }
    };
    
    return foo;
};

const curriedAdd = curryAdd();
console.log(curriedAdd(1,2)(2,2)(3,4)(4,6)());

在这个更加复杂的柯里化中,curryAdd函数可以接受任意数量参数,计算合后返回内部函数foo,当foo被调用时,接受到更多的参数,它会递归调用curryAdd并将新的参数与已有参数合并,没有更多参数时,返回total。

注: reduce方法接受一个回调函数作为参数,这个函数接受两个参数,一个当前值,一个当前数组元素,这个回调函数会在数组的每个元素上调用一次。在接受一个初始值,这里为0。

相关推荐
并不会44 分钟前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
悦涵仙子1 小时前
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
javascript·css·sass
衣乌安、1 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜1 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师1 小时前
CSS的三个重点
前端·css
耶啵奶膘2 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿5 小时前
webWorker基本用法
前端·javascript·vue.js