2021-06-14 JS函数柯里化

函数柯里化思想

预先存储(预处理),利用闭包的“保存机制”,我们把一些值事先存储起来,供其下级上下文中后期使用
例:(百度的一道面试题)
实现函数,让其具有如下功能

let res = fn(1,2)(3);
console.log(res); //=>6  1+2+3

答:

const fn = (...params) => {
    return (...args) => {
        params = params.concat(args);
        return params.reduce((result, item) => result + item);
    };
};
let res = fn(1, 2)(3);
console.log(res); //=>6  1+2+3 

加强版:如果不知道函数执行的次数呢?

答:

// 基于console.log或者alert输出一个函数,会默认先把函数转化为字符串「Symbol.toPrimitive -> valueOf -> toString」,然后再输出「只不过浏览器为了让开发者知道这是个函数字符串,所以在输出的字符串前面,加了一个“f”」
const curring = function curring() {
    let params = [];
    const add = (...args) => {
        // 把每一次ADD执行传递的实参拼接到PARAMS中
        params = params.concat(args);
        return add;
    };
    // 重写ADD的Symbol.toPrimitive,实现输出ADD函数的时候,把之前PARAMS中存储的值求和
    add[Symbol.toPrimitive] = function toPrimitive() {
        return params.reduce((result, item) => result + item);
    };
    return add;
};

let add = curring();
let res = add(1)(2)(3);
console.log(res); //->6

add = curring();
res = add(1, 2, 3)(4);
console.log(res); //->10

add = curring();
res = add(1)(2)(3)(4)(5);
console.log(res); //->15

管道函数

在函数式编程当中有一个很重要的概念就是函数组合, 实际上就是把处理数据的函数像管道一样连接起来, 然后让数据穿过管道得到最终的结果。 例如:
const add1 = (x) => x + 1;
const mul3 = (x) => x * 3;
const div2 = (x) => x / 2;
div2(mul3(add1(add1(0)))); //=>3

而这样的写法可读性明显太差了,我们可以构建一个compose函数,它接受任意多个函数作为参数(这些函数都只接受一个参数),然后compose返回的也是一个函数,达到以下的效果:
const operate = compose(div2, mul3, add1, add1)
operate(0) //=>相当于div2(mul3(add1(add1(0))))
operate(2) //=>相当于div2(mul3(add1(add1(2))))

简而言之:compose可以把类似于f(g(h(x)))这种写法简化成compose(f, g, h)(x),请你完成 compose函数的编写

const add1 = x => x + 1;
const mul3 = x => x * 3;
const div2 = x => x / 2;

const compose = function compose(...funcs) {
    let len = funcs.length;
    if (len === 0) return x => x;
    if (len === 1) return funcs[0];
    return function operate(x) {
        return funcs.reduceRight((result, func) => {
            return func(result);
        }, x);
    };
};
const operate = compose(div2, mul3, add1, add1);
console.log(operate(0));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值