初识柯里化

110 阅读2分钟

从简入繁:详解 JS 柯里化,实现 add(1, 2)(3)(4, …)(5, …)… 无限累加函数。

什么是柯里化

  • 官方定义:把一个接收多个参数的函数,设计成一个:接收单一参数的函数,并返回一个能够接收剩余参数的新函数,最后返回结果。
  • 简单理解:调用函数A运行后返回函数B,B处理A剩余参数并返回函数C,C处理B剩余参数并返回函数D,...,最后返回结果。

// 普通函数 const add = (a, b, c) => {     return a + b + c }

// 柯里化函数
const curry_add = (a) => {     return (b) => {         return (c) => {             return a + b + c         }     } }

改造和拆解

1. 简单的递归函数

const curry_add = (a) => {    return curry_add }

curry_add(1)(2)(3)(4)...

  • 思考:返回递归函数的同时,如何将每次执行结果的值存储在函数中?

2. 像极了闭包和记忆函数

 const curry_add=(a)=>{
     let num =a||0
     const item=(b)=>{
        num+=b;
      return item 
     }
    return item
 }

在 curry_add 函数被初次调用时,创建了一个拥有 num 变量 和 item 函数 的作用域函数,在第二次和后面的执行过程中,只是一直在 累计 num 和 调用 item 的重复工作,直到 curry_add 函数执行结束并销毁 num 和 item。

  • 思考:如果将结果传递透出?

3. 不那么严谨的万物皆对象(简单实现)

    const curry_add = (a) => {  
        let num = a || 0  
        const item = (b) => {  
            num+= b  
            item.num = num // 将 num 赋到函数上  
            return item  
        }  
        return item  
    }
  • 思考:如何在执行结束后返回结果而中间步骤返回函数?

    const curry_add = (a) => {  
        let num = a || 0  
        const item = (b) => {  
            num+= b  
            return item  
        }  
    
    item.toString = () => {  
        console.log('参数变化,自动触发')  
        return num  
    }  
    
    return item  
    }
    
    
  • 官方说明:Object.prototype.toString() 方法返回一个表示该对象的字符串,当对象被表示为文本值时 或者当以期望字符串的方式引用对象时,该方法被自动调用。

5. 展开运算符 ...

 const curry_add=(...a)=>{
     let num=a.reduce((t,c)=>{t+c,0})
  const  item =(...b)=>{
     num=num+b.reduce((t,c)=>{t+c},0)
     return item
  }
  item.toString=()=>num
  return  item
 }

初次执行用 reduce 计算结果,在递归函数中也加入 reduce 累加结果,reduce 为函数基本操作,无内容补充