跟underscore一塊兒學函數式編程

導讀

在寫這篇文章以前,一直比較猶豫要不要寫,一來是以爲函數式編程自己更多的是一種編程思想,怕表達的不夠清楚,二來這塊相對較難,平時又實踐的少。可是在各種公衆號包括掘金看到過不少關於函數式的文章,很強大,可是隻知其一;不知其二,因此我以爲頗有必要從underscore爲切入點,來理解和運用函數式編程,但願你們能和我一塊兒把函數式應用於咱們的平常編碼之中,使咱們的代碼拓展性和靈活性大大加強。 javascript

概述

"函數式編程"是一種"編程範式"(programming paradigm),是一種優秀的編程思想。"函數式編程"就是將一系列聲明式函數經過自由組合的方式構建出咱們須要實現的功能,其中各個函數的功能職責單一,相互解耦。對於需求將各個函數進行按需組合便可,當新的需求來的時候,只須要從新添加函數或者再自由組合。因此函數式編程是「組合優於繼承」,「聲明式」,「高內聚,低耦合」,「高拓展性和靈活性」思想的具體體現。本文不想引發FP和OOP的爭議,旨在讓讀者可以理解和運用FP進行開發。
在一開始,我先使用mqyqingfeng大大舉的一個例子來解釋函數式編程:
需求html

咱們須要寫一個函數,輸入 'kevin',返回 'HELLO, KEVIN'。java

通常實現git

var greet = function(x){
	return 'HELLO,'+x.toUpperCase();
}
複製代碼

根據以前的概念,使用函數式編程github

var toUpperCase = function(x) { return x.toUpperCase(); };
var hello = function(x) { return 'HELLO, ' + x; };

var greet = function(x){
    return hello(toUpperCase(x));
};

greet('kevin');
複製代碼

此處greet就是將hello和toUpperCase進行組合獲得,hello和toUpperCase是純函數,此時輸入kevin,輸出HELLO, KEVIN。
編程

image.png

如圖,咱們把greet當作一個黑盒,hello,toUpperCase,...是聲明式函數,經過鏈接線將它們自由組合,組成greet1,greet2,...,用於只須要關注greet的功能,輸入和輸出便可redux

在此處必須指明的是hello和toUpperCase必須是純函數,保證這個黑盒,在輸入相同數據的狀況下,輸出必定相同。數組

var compose = function(f,g) {
    return function(x) {
        return f(g(x));
    };
};
var greet = compose(hello, toUpperCase);
greet('kevin');
複製代碼

上述使用compose對函數f和g進行組合封裝,使用x做爲高階函數compose(a,b,c,d...)的輸入,執行compose函數返回須要的值。 app

實現

下面摘自underscore官網對於compose的解釋和使用方式:    
ide

image.png

underscore官網對於compose的釋義和使用方式通俗易懂

在概述中,咱們hello,toUpperCase進行組合的實現以下

var greet = function(x){
    return hello(toUpperCase(x));
};
複製代碼

在設計compose的實現時,上述顯然是不合適的。首先compose返回function,其次形參是fn,咱們先打個框框出來:

var compose = function() {
    var args = arguments;
    var start = args.length - 1;
    return function() {
				//獲取傳入compose的參數,而且從右往左,將結果迭代執行
    };
  };
複製代碼

進一步實現

_.compose = function() {
    var args = arguments;
    var start = args.length - 1;
    return function() {
      var i = start;
      var result = args[start].apply(this, arguments);
      while (i--) result = args[i].call(this, result);
      return result;
    };
  };
複製代碼

Compose源碼實現

上述正是underscore的源碼實現。
注:對於compose中的形參fn,若是參數大於1,可使用函數柯里化降維。

總結

本文寫的比較簡潔,篇幅少,旨在但願你們可以看完就懂,而且可以在實際開發中應用進去。特別是在React的開發中,redux,高階組件也是compose思想的體現

參考文章

《函數式編程初探》
《函數式編程,真香》
《JavaScript函數式編程,真香之組合函數(二)》
《JavaScript專題之函數組合》
《JS 函數式編程指南》
《反對函數式編程的政治正確》

相關文章
相關標籤/搜索