关于 JavaScript 中柯里化函数的实现,附带详细解析!

举报
CoderBin 发表于 2022/11/03 15:10:01 2022/11/03
【摘要】 大家好,我是 CoderBin,在面试当中,手撕代码的场景屡见不鲜,手写 JS 当中的方法更是最常见的一种,所以本文将全面的,详细解析柯里化函数的实现原理,并手写出自己的柯里化函数,相信看完本文的小伙伴都能从中有所收获💪。 创作不易,你们的点赞收藏留言就是我最大的动力💓 如果文中有不对、疑惑的地方,欢迎各位小伙伴们在评论区留言指正🌻

前言

大家好,我是 CoderBin,在面试当中,手撕代码的场景屡见不鲜,手写 JS 当中的方法更是最常见的一种,所以本文将全面的,详细解析柯里化函数的实现原理,并手写出自己的柯里化函数,相信看完本文的小伙伴都能从中有所收获💪。

创作不易,你们的点赞收藏留言就是我最大的动力💓

如果文中有不对、疑惑的地方,欢迎各位小伙伴们在评论区留言指正🌻

1. 函数作用

调用柯里化函数,并传递一个想转换成柯里化函数的函数,得到一个新函数,可对该新函数进行柯里化的调用得到最终结果

2. 总体步骤

  1. 柯里化函数最终会返回一个函数,所以,先定义一个 curried 函数,最后再返回
  2. 在 curried 函数里面先进行参数个数的判断

3. 详细步骤

  1. 柯里化函数最终会返回一个函数,所以,先定义一个 curried 函数,最后再返回

  2. 在 curried 函数里面先进行参数个数的判断

    • 参数已满时,直接用 apply 方法调用传入的函数并返回
    • 参数未满时,直接返回一个定义的函数,在里面递归使用 apply 方法 调用 curried 函数并返回

4. 代码实现

/**
 * * 柯里化函数实现
 * @param {Funcion} fn 想转换成柯里化的函数
 * @returns 
 */
function binCurrying(fn) {
  function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args)	// 参数已满时
    } else {
      return function (...args2) {
        return curried.apply(this, [...args, ...args2])	// 参数未满时
      }
    }
  }
  return curried
}

5. 测试代码

// 测试代码
function add1(x, y, z) {
  return x + y + z
}

// 调用 binCurrying 函数,得到柯里化函数
let curryAdd = binCurrying(add1)  

console.log(curryAdd(10, 20, 30)) // 60
console.log(curryAdd(10, 20)(30)) // 60
console.log(curryAdd(10)(20)(30)) // 60

6. 细节解析

  1. 返回的 curried 函数参数必须用展开运算符展开,因为不确定会传入几个参数
  2. fn.length 得到的是 fn 函数参数的长度(个数)
  3. 调用 fn 函数是要使用 apply 方法调用,并且将 this 改为正确的指向,因为不清楚得到柯里化函数后,是由什么方式调用的
  4. 在参数未满时返回的函数中,接收的参数也要用展开运算符展开
  5. 在递归使用 apply 方法调用 curried 函数时,第二个参数要将上一次的参数与这一次的参数进行拼接成为一个数组

7. 核心原理

进行参数是否满足的判断,如果不满足,就要递归使用 apply 方法调用 curried 函数,第二个参数要将上一次的参数与这一次的参数进行拼接成为一个数组进行传递。通过不断地递归调用,等到满足条件时,所有的参数就会组成一个数组进行调用得到结果并返回


每文一句:科学的自负比起无知的自负来还只能算是谦虚。

本次的分享就到这里,如果本章内容对你有所帮助的话欢迎点赞+收藏。文章有不对的地方欢迎指出,有任何疑问都可以在评论区留言。希望大家都能够有所收获,大家一起探讨、进步!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。