讓我們假裝現在要完成一個任務:盡可能按照函數式語言的原則來寫JavaScript程式碼。
接下來一系列文章就是為了讓你們和我一起開始這樣一段旅程。首先,我們需要修正一些你們腦中可能有的函數式語言錯誤的概念。
JS語言中的函數式被嚴重誤解。
很顯然,有相當多的開發者要每天用JavaScript的函數式範式 。我想說有更大一部分JavaScript 開發者沒有真正理解這些東西。
我認為造成這個的原因是絕大多數用於Web伺服器端的開發語言都是來自C,而大家都知道這些語言不是函數式語言。
一般有兩個層面的困惑。第一層是關於以下範例中的用法,這是jQuery中非常常見的用法:
$(".signup").click(function(event){ $("#signupModal").show(); event.preventDefault(); });
在上面這段程式碼中:我們傳了一個匿名函數作為參數,這就是在JavaScript 中臭名昭著的回呼函數。這些函數會被呼叫嗎?根本不會!
上面這個例子說明了函數式語言的一個關鍵特徵:函數是一種參數。另一方面,這個例子只用三行程式碼違反了幾乎所有能違反的函數式程式設計範式。
第二層的疑惑是更微妙的。看看這個:只有少數時髦的JS開發者是這樣看自己的:
嗯,真不錯!但是我已經完全了解函數式編程,我在所有的專案中都使用了Underscore.js。
Underscore.js是一個非常有名且隨處可見的JavaScript 函式庫。舉個例子:假設我有一組詞,並且我需要每個詞對應的前兩個字母。這用Underscore.js寫非常簡單:
var firstTwoLetters = function(words){ return _.map(words,function(word){ return _.first(word,2); }); };
看這個JavaScript 範例。我用了函數式中精緻實用的函數:_.map和_.first。對於這個大家有什麼想法?
雖然underscore.js和 _.map這樣的函數都是很有用的函數式範式,但是像這個例子中這樣把這些東西放在一起還是讓我感到有些難以理解。我們真的需要這樣做嗎?
如果我們開始思考怎樣才能更加“函數式”,也許我們可以把上面的例子改寫成這樣:
// ...a little bit of magic var firstTwoLetters = map(first(2));
仔細想想,這一行程式碼和上面的5行是一樣的效果。很多字只是參數或占位符。真正的邏輯在於把map函數、first函數和常數2用有意義的方式組合在一起。
有些人可能在想:這個例子中的神奇之處在哪裡?畢竟,說任何一個例子神奇都有點像吹噓,對吧?
我正打算用接下來的兩篇文章來解釋上面這個例子到底神奇在哪,如果你好奇的話,可以繼續往下看。
這一系列部落格是為了幫助大家怎麼把函數式程式設計的美妙之處應用到你的JavaScript程式碼中。
下一節中,我將討論JavaScript 語言中函數式及非函數式的多種元素。有了這些知識,我們可以透過把這些元素整合在一起,慢慢的在腦中形成函數式程式設計的完整體系,並且理解它們在JavaScript中的表現。