若想實現一個將多位數組的數值累加的總和的需求:
方式一:
let arr = [1, [2, 2], [3, 3]];
let arr1 = arr.flat(Infinity).reduce((total, value, index, arr) => {
return total + value;
}, 0);
console.log('arr1:', arr1);
經過函數式編程方式
方式二:
//es5html
function add(x) {
return function addFun(y) {
if (y) {
return add(x + y); //能夠遞歸屢次調用,但須要以後一次調用()執行
} else {
return x;
}
}
}
let result = add(1)(2)(3)();
console.log('add(1)(2)(3)():', result);
let arr2 = arr.flat(Infinity).reduce((totalFun, value) => { return totalFun(value); }, add);
console.log('arr2:', arr2());
方式三:
//es6方式es6
let sum = (x) => (y => {
if (y) {
return sum(x + y);
}
return x;
});
let sum1 = sum(1);
let sum2 = sum1(2);
console.log(`sum2:${sum2},\r\n result:${sum2()}`);
道破:
一下內容來源:(謝各位大神的指導)
內容如有問題,各位客官可留言,我會及時修復di~。
[1] (https://blog.csdn.net/archimelan/article/details/81940858)
[2] (http://www.javashuo.com/article/p-kxfpnwtk-eh.html)
[3] (https://blog.csdn.net/weixin_43430036/article/details/93721442#_140)
[4] (https://www.liaoxuefeng.com/wiki/897692888725344/923030136026784)編程
優勢:
- 編寫的函數高內聚,低耦合
- 提升了可複用性
- 無臨時變量過多或堆棧過多致使的反作用。
無反作用(side-effect free) 和 不包含賦值語句 (contain no assignment statements)。所以,表達式能夠在任什麼時候候計算並替換爲其值, 這樣程序就是引用透明的(referentially transparent)。即便到了今天也常常討論計算時值不可變(value of immutability)和無反作用(side-effect free)
- 只是計算過程,內部無狀態,從而能夠在併發的狀況保證狀態一致。
函數式編程的三大特性:
- immutable data 不可變數據:
像Clojure同樣,默認上變量是不可變的,若是你要改變變量,你須要把變量copy出去修改。這樣一來,可讓你的程序少不少Bug。由於,程序中的狀態很差維護,在併發的時候更很差維護。(你能夠試想一下若是你的程序有個複雜的狀態,當之後別人改你代碼的時候,是很容易出bug的,在並行中這樣的問題就更多了)
- first class functions:
這個技術可讓你的函數就像變量同樣來使用。也就是說,你的函數能夠像變量同樣被建立,修改,並當成變量同樣傳遞,返回或是在函數中嵌套函數。這個有點像Javascript的Prototype(參看Javascript的面向對象編程)
- 尾遞歸優化:
咱們知道遞歸的害處,那就是若是遞歸很深的話,stack受不了,並會致使性能大幅度降低。因此,咱們使用尾遞歸優化技術——每次遞歸時都會重用stack,這樣一來可以提高性能,固然,這須要語言或編譯器的支持。Python就不支持。
函數式編程的幾個技術
- map & reduce :
這個技術不用多說了,函數式編程最多見的技術就是對一個集合作Map和Reduce操做。這比起過程式的語言來講,在代碼上要更容易閱讀。(傳統過程式的語言須要使用for/while循環,而後在各類變量中把數據倒過來倒過去的)這個很像C++中的STL中的foreach,find_if,count_if之流的函數的玩法。
- pipeline:
這個技術的意思是,把函數實例成一個一個的action,而後,把一組action放到一個數組或是列表中,而後把數據傳給這個action list,數據就像一個pipeline同樣順序地被各個函數所操做,最終獲得咱們想要的結果。
- recursing 遞歸 :
遞歸最大的好處就簡化代碼,他能夠把一個複雜的問題用很簡單的代碼描述出來。注意:遞歸的精髓是描述問題,而這正是函數式編程的精髓。
- currying:
把一個函數的多個參數分解成多個函數, 而後把函數多層封裝起來,每層函數都返回一個函數去接收下一個參數這樣,能夠簡化函數的多個參數。在C++中,這個很像STL中的bind_1st或是bind2nd。
- higher order function 高階函數: 所謂高階函數就是函數當參數,把傳入的函數作一個封裝,而後返回這個封裝函數。現象上就是函數傳進傳出,就像面向對象對象滿天飛同樣。