JS 模拟实现 curry、compose 方法

267 阅读1分钟

一、模拟实现 curry 方法

1. curry 化函数作用

把一个函数 curry 化后,可以分多次执行,每次传入不同数量的参数,等到传入的参数个数比原函数的参数个数多时,开始执行

add(1)(2)(3)

2. 模拟实现原理

每次调用 curry 化后的函数时,利用闭包原理保存参数个数

3. 代码实现

// 把 fn 函数 curry 化
function curry(fn) {
    const len = fn.length
    // 把 curry 化函数的参数长度传递下去
    return _curry.call(this, fn, len)
}

// 递归调用保存参数
function _curry(fn, len, ...argus) {
    return function(...params) {
        const _argus = [...argus, ...params]
        if (_argus.length >= len) {
            return fn.apply(this, _argus)
        } else {
            return _curry.call(this, fn, len, ..._argus)
        }
    }
}

// 更新一种更简洁的实现方式
const curry = (fn, argus) => {
    fn.length <= argus.length 
    // 传的参数符合 fn 函数的参数个数,执行 fn 函数
    ? fn(...argus) 
    // 比 fn 函数的参数少,拼好参数继续执行 curry 函数
    : (_argus) => curry(...argus, ..._argus) 
}

二、模拟实现 compose 方法

1. compose 方法作用

传入多个函数作为参数,最终返回一个新函数,根据传入的多个函数参数,依次从右到左执行,最终返回执行结果。例如 redux 的 applyMiddleware 方法

2. 代码实现

function compose(...funs) {
    if (funs.length === 0) {
        return argus => argus
    }
    if (funs.length === 1) {
        return funs[0]
    }
    return funs.reduce((a, b) => {
        return argus => a(b(...argus))
    })
}