前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手写柯里化 - toString 理解

手写柯里化 - toString 理解

作者头像
掘金安东尼
发布2022-09-19 10:43:40
2870
发布2022-09-19 10:43:40
举报
文章被收录于专栏:掘金安东尼

theme: juejin

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情


在前面一篇文章《**为什么我要说:柯里化 == 闭包+递归?** 》中,我们提到:

柯里化可以通过闭包+递归实现

代码语言:javascript
复制
let arr = []
function addCurry() {
   let arg = Array.prototype.slice.call(arguments); // 收集参数
   arr = arr.concat(arg);
    if (arg.length === 0) { // 如果参数为空,则判断递归结束
        return arr.reduce((a,b)=>{return a+b}) // 求和
    } else {
        return addCurry;
    }
}

addCurry(1)(2)(3)() // 6

这样写,没什么毛病,通过:Array.prototype.slice.call(arguments) 收集了参数,推到 arr 数组里;当存在参数时,递归调用,当没有参数的时候,再用 reduce() 求和,返回;

但是这样写,会有外部变量 arr,arr 不清理的话,会被一直保存,导致连续调用出错:

代码语言:javascript
复制
addCurry(1)(2)(3)() // 6
addCurry(1)() // 7

所以,需要改写成这样:

代码语言:javascript
复制
function addCurry() {
    let arr = [...arguments]
    let fn = function () {
        if(arguments.length === 0) {
        return arr.reduce((a, b) => a + b)
        } else {
            arr.push(...arguments)
            return fn
        }
    }
    return fn
}

把 arr 再加一层封装到函数里,每次调用,都会重新声明,原值会被清理;

之前相加的思路仍然不变;

但这样做,还有一个问题:总是需要用空括号 () 为结尾,来判断结束调用;

能不能去掉这个,直接如下这样就能求值:

代码语言:javascript
复制
addCurry(1)(2)(3)

//或

addCurry(1)(2,3)

答案是可以的,原理是用到 toString ,当用 Function 的值做计算的时候,会调用 toString 做隐式转换;

代码语言:javascript
复制
let fn = function(){}

fn.toString = () => 1

fn == 1 // true

所以,我们的代码更新为:

代码语言:javascript
复制
function addCurry() {

    let arr = [...arguments]

    // 利用闭包的特性收集所有参数值
    var fn = function() {
        arr.push(...arguments);
        return fn;
    };

    // 利用 toString 隐式转换
    fn.toString = function () {
        return arr.reduce(function (a, b) {
            return a + b;
        });
    }
    return fn;
}

addCurry(1)(2)(3) == 6 // true

这里一定要注意,直接打印 addCurry(1)(2)(3) 是不能拿值的,只有当它做隐式转化的时候,才能计算得正确得值。

小结:

其实不管是用空括号 () 作“开始执行reduce相加”的判断依据,还是用 toString 的隐式转换做依据,总是要有一个标准,来告诉柯里化函数:你可以执行了!

柯里化精髓是参数收集,是延迟执行!

延迟就是 JS 函数闭包的精髓设计!!

OK,以上便是本篇分享。点赞关注评论,为好文助力👍 我是掘金安东尼 🤠 100 万阅读量人气前端技术博主 💥 INFP 写作人格坚持 1000 日更文 ✍ 陪你一起度过漫长岁月 🌏

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: juejin
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档