面试题:函数柯里化

题目

发现一道有意思的面试题:如何实现 add(1)(2)(3)=6

首先简单分析一下,我们就能发现这是一个函数传值 return3次得到6

简单实现

function add(a) {
    return function (b) {
        return function (c) {
            return a + b + c;
        }
    }
}

利用闭包,执行add函数时return一个匿名函数,用于最终返回结果。

当然,这个方法有个明显缺陷,就是如果函数变成 add(1)(2)(3)(4) ,我们就又要手动嵌套一层。

分析

有没有什么办法呢? 有!

我们先把这个问题简化一下:

如何实现函数对自身的调用呢,如: add()()() ?

function add () {
    // 方法1:利用apply
    return function () {
        return add.apply();
    }
    // 方法2:
    // return add;
}

那么,问题就可以这么实现:

function add () {
    var args = Array.prototype.slice.call(arguments);
    console.log(args);
    var fn = function () {
        var fn_args = Array.prototype.slice.call(arguments);
        return add.apply(null, args.concat(fn_args));
    };
    return fn;
}

至此, add 函数的多层嵌套以及所有参数,我们都拿到了,下面只需要把参数相加就可以了。

但我们不能直接相加,因为我们 add 函数 return add.apply() 返回的是函数, 因此即使相加,值我们也是拿不到的。

valueOf

这里我们要用到 valueOf 方法。
valueOf 方法返回指定对象的原始值。

function add () {
    var args = Array.prototype.slice.call(arguments);
    var fn = function () {
        var fn_args = Array.prototype.slice.call(arguments);
        return add.apply(null, args.concat(fn_args));
    };
    fn.valueOf = function () {
        return args.reduce(function (a, b) {
            return a + b;
        });
    };
    return fn;
}

搞定!现在这个方法不仅支持 add(1)(2)(3) 而且支持 add(1,2,3)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值