js使用reduce實現組合函數

題目描述

/**
 * 函數組合運行
 * 說明:實現一個方法,可將多個函數方法按從左到右的方式組合運行。
 *   如`composeFunctions(fn1,fn2,fn3,fn4)`等價於`fn4(fn3(fn2(fn1))`。
 * 示例:
 *  const add = x => x + 1;
 *  const multiply = (x, y) => x * y;
 *  const multiplyAdd = composeFunctions(multiply, add);
 *  multiplyAdd(3, 4) // 返回 13
 */

分析

由於ES6給數組新增了reduce方法,所以該功能實現起來比較方便。reduce函數接收兩個參數:迭代函數(該函數有四個參數)和迭代的初始值(可選)。於是我們寫出如下的代碼:

function composeFunctions(...fns) {
    return function (arg) {
        return fns.reduce((args, fun) => fun(args), arg)
    }
}

但是這種寫法有一個問題,就是迭代的第一個函數只能接受一個參數。聰明的你可能想到了擴展運算符,但是你會發現簡單的在arg參數前面加…之後並不會得到我們預期的結果。解決方案如下:
通過參數解構賦值的方式把第一個迭代的函數改造爲單參數的形式:const multiply = ([x, y]) => x * y;
通過數組把參數包裹起來,實現單參數,然後在接收的地方使用擴展運算符將其展開就可以了。

代碼展示

const add = x => x + 1;
const multiply = ([x, y]) => x * y;  // 將第一個迭代的函數改造成單參數(數組參數)

function composeFunctions(...fns) {
    return function (...arg) {  // 在此處對參數進行解構
        return fns.reduce((args, fun) => fun(args), arg)
    }
}

const multiplyAdd = composeFunctions(multiply, add);
console.log(multiplyAdd(3, 4));  // 13

寫在後面

這種組合的編程思想是很有用的,將一個個單一職責的函數組合起來實現不同的需求,可以最大限度的實現函數的複用。而且這種複用在很多情況下要比繼承好得多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章