js中的函数柯里化思想

柯里化: 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

面试中嘴jian,提了一下函数柯里化思想,面试官反问我函数柯里化有哪些应用场景,回答了只知道bind的内部实现,还好面试官说在实际工作中也不常用,问题不大。不过名字叫得这么高大上,还是了解一下比较好。

概念过于抽象,看下面例子马上理解:

// 普通的add函数
function add(x, y) {
    return x + y
}
// 柯里化后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

bind(不会立即执行)也是经典的柯里化例子,看看bind的内部实现:

//bind内部实现
Function.prototype.bind = function(context) {
    let cxt = JSON.parse(JSON.stringify(connext)) || window;
    cxt.func = this;
    //获取实参
    let args = Array.from(arguments).slice(1);
    //返回函数
    return function() {  //通过闭包预存第一次传的参数
        let allArgs = args.concat(Array.from(arguments));
        return allArgs.length > 0 ? cxt.func(...allArgs) : cxt.func();
    }
}

(闭包是函数柯里化的灵魂,有信心的话回答闭包的应用时可以顺便一提,然后…)

// 支持多参数传递
function progressCurrying(fn, args) {

    var _this = this
    var len = fn.length;
    var args = args || [];

    return function() {
        var _args = Array.prototype.slice.call(arguments);
        Array.prototype.push.apply(args, _args);

        // 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
        if (_args.length < len) {
            return progressCurrying.call(_this, fn, _args);
        }

        // 参数收集完毕,则执行fn
        return fn.apply(this, _args);
    }
}

总结一下优点:延迟执行,可多次传参。

经典面试题:


// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3)(4)(5) = 15;
add(1, 2, 3)(4)(5) = 15;
add(1)(2)(3)(4)(5) = 15;

function currying(fn, length) {

    length = length || fn.length; //fn.length:被柯里化的函数形参的个数
    
    return function(...args) {
        if (args.length >= length) { //判断参数是否收集完毕
            return fn(...args);  // 参数收集完毕,则执行fn
        } else {
            return currying(fn.bind(null, ...args), length - args.length);
        } // 参数未收集完毕,则递归调用fn,继续收集参数
    }
}

let add = currying((...arg) => eval(arg.join('+')), 5);

let a = add(1)(2)(3)(4)(5)
let b = add(1, 2, 3)(4)(5)
let c = add(1)(2)(3)(4)(5)
console.log(a); //15
console.log(b); //15
console.log(c); //15

eval( ) :将字符串转为可执行的js代码

参考文章:详解JS函数柯里化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JS柯里化是一种函数式编程的技术,由阮一峰在其博客首次介绍。所谓柯里化,就是将一个接受多个参数的函数转变为接受单一参数的函数序列的过程。 柯里化的主要思想是延迟计算。通过柯里化,可以将一个具有多个参数的函数转化为一个接收单一参数的函数,这样的函数可以等到所有参数都准备好之后再进行计算。这样做的好处是可以将函数的使用更加灵活,调用的时候可以逐个传入参数,也可以一次性传入多个参数。另外,这样还可以用来创建一些固定部分参数的新函数,提高代码的复用性。 在JS柯里化可以通过函数递归的方式实现。函数递归地返回一个新函数,新函数可以保存已接收到的参数,并在接收新参数后进行计算和返回。因为JS函数可以作为一等公民,可以作为参数和返回值,所以可以非常方便地实现柯里化柯里化在实际应用非常有用。比如在函数式编程柯里化可以用来创建高阶函数,可以根据传入的参数动态生成一个新的函数。另外,柯里化还可以用来解决数据优先编程的问题,即将传入的数据先与函数返回的新函数结合,然后再进行计算。 总之,JS柯里化是一种将多参数函数转化为接收单一参数的函数序列的技术,可以通过函数递归实现。柯里化的应用非常广泛,可以用于创建高阶函数和解决数据优先编程的问题。阮一峰在其博客详细解释了柯里化的概念和实现方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值