JS函數式編程【譯】3.2 開發和生產環境

開發和生產環境

環境

編程風格與應用所部署或者將要部署的環境沒啥關係。可是庫就有關係了。html

瀏覽器

主要的Javascript應用仍是跑在客戶端的,也就是瀏覽器。基於瀏覽器的環境對於開發來講很是好, 由於瀏覽器無處不在,你能夠在本地機器上寫代碼,解釋器是瀏覽器的Javascript引擎, 全部的瀏覽器都有開發者終端。火狐的FireBug提供了很是有用的錯誤信息,並支持斷點等等, 不過一樣的代碼運行在Chrome和Safari上的交叉引用的錯誤輸出會頗有用。甚至連IE都包含開發者工具。 node

瀏覽器的問題是他們對Javascript的解析不盡相同!儘管不是廣泛現象,可是可能有些代碼在不一樣的瀏覽器上會獲得很是不一樣的結果。 不過主要的差異在於它們如何處理DOM,而不是在原型和函數如何工做上。舉個明顯的例子,Math.sqrt(4) 在任何瀏覽器和shell上都會返回2。可是scrollLeft方法依賴於瀏覽器的佈局策略。 程序員

編寫針對瀏覽器的特定代碼是在浪費時間,這也是爲什麼要使用庫的另一個緣由。web

服務器端Javascript

Node.js已經成爲建立服務器端和基於網絡應用的標準平臺。函數式編程能夠用於服務器端應用的編程嗎? 能夠!OK,不過如今的這些函數式庫是爲這種注重性能的環境設計的嗎?答案仍然是確定的。 shell

這章提到的全部的函數式庫均可以工做在Node.js上,有些須要依賴browserify.js模塊來處理瀏覽器元素。數據庫

服務器端環境的一個函數式用例

在咱們的網絡系統這個無畏的新世界裏,服務器端應用開發人員總在擔憂併發問題,這是應該的。 經典的例子就是一個應用容許多個用戶修改同一個文件,若是他們打算同時修改這個文件,你將會陷入使人做嘔的混亂。 這就是困擾了程序員幾十年的狀態維持問題。 編程

假設下面這個情景:瀏覽器

  1. 一天早晨,亞當打開了一份報告開始編輯,可是出去吃午餐的時候沒有保存。
  2. 比利打開了同一份報告,添加了內容,而且保存了報告。
  3. 亞當吃完午餐回來,又往這份報告裏添加了內容,而且保存,不知情地覆蓋了比利的內容。
  4. 次日,比利發現他的內容消失了。他的老闆衝他咆哮,全部的人都一塊兒衝着開發人員發飆,結果開發人員丟了工做。

長期以來,解決這個問題的辦法就是給文件創建狀態。當有人編輯這個文件的時候就把狀態切換爲加鎖, 這就防止其餘人編輯這個文件,並在保存這個文件後把狀態切換爲解鎖。在咱們的情景裏,比利應該沒法修改報告, 直到亞當吃完飯回來。而且只要文件沒被保存就沒有其餘人能夠編輯它。 bash

這正是函數式編程關於不可變數據和狀態的思想具備實際意義之處。函數式的實現並非直接修改文件, 而是修改文件的一個拷貝,也就是一個新的版本。若是要保存這個版本而此時一個新的版本已經存在, 咱們就知道已經有別人修改了原來的文件。危險規避了。 服務器

如今這個場景能夠這樣展開了:

  1. 一天早晨,亞當打開了一份報告開始編輯,可是出去吃午餐的時候沒有保存。
  2. 比利打開了同一份報告,添加了內容,保存爲了一個新的版本。
  3. 亞當吃完飯回來繼續添加內容,當他要保存時,系統告訴他如今已經存在一個新版本了。
  4. 亞當打開了這個新版本,添加了本身的內容,並保存爲另外一個新版本。
  5. 經過查看版本歷史,老闆看到了一切在平穩運行。全部人都很開心,應用的開發人員也獲得了晉升和獎賞。

這個叫作事件源。不須要維護明確的狀態,只須要事件。這個過程很是清晰,整個事件的歷史均可以回顧。

這個思想以及其它一些優點是函數式編程在服務器端日益增加的緣由。

CLI

儘管web和node.js是兩個主要的Javascript環境,可是一些務實和進取的用戶在尋找把Javascript用於命令行的方式。

把Javascript做爲一個命令行界面(CLI)腳本語言使用會是應用函數式編程的一個絕佳機會。 想象一下在搜索本地文件時使用惰性求值,或把整個bash腳本用函數式的Javascript寫成一行。

與其它Javascript模塊一塊兒使用函數式庫

web應用由許多東西組成:框架、庫、API等等。他們能夠互相依賴,做爲對方的插件,或者僅僅是共存的對象。

  • Backbone.js
    • 一個使用RESTful JSON的MVP(model-view-provider)框架
    • 須要underscore.js庫,這是backbone的惟一必需依賴
  • jQuery
    • Bacon.js經過綁定融入jQuery
    • Underscore和jQuery很好地互補
  • Prototype
    • 提供與Ruby的Enumerable風格相近的一系列函數
  • Sugar.js
    • 修改原生對象及其方法
    • 和其它庫混合使用時需當心,尤爲是Prototype

編譯爲Javascript的函數式語言

有時Javascript函數式核心以外那厚重的C外衣讓你想要換一個函數式語言。好,能夠滴!

  • Clojure和ClojureScript
    • Clojure是一個現代的Lisp實現,是一個具有所有函數式特徵的語言
    • ClojureScript將Clojure編譯爲Javascript
  • CoffeeScript
    • CoffeeScript是一個函數式語言及其編譯器的名稱,它編譯爲Javascript
    • CoffeeScript表達式和Javascript表達式能夠一一對應

這樣的語言還有不少,包括Pyjs、Roy、TypeScript、UHC、PureScript等等。

第三章總結

你選擇使用哪一個數據庫取決於你的須要是什麼。須要函數響應式編程來處理事件和動態值?使用bacon.js。 須要無限流而不須要別的?用stream.js。想要一個函數式助手來補充jQuery?試試underscore.js。 須要嚴格特定多態的結構化環境?看看bilby.js。須要面面俱到的函數式編程工具?使用Lazy.js。 用這些都不爽?你本身寫一個。

任何庫都只擅長於它所使用的方式。儘管這章提到的庫裏面有幾個缺點不多,大多數錯誤都會在不經意間就出現。 這取決於你選擇的庫是否正確,是否符合你的需求。

若是咱們在Javascript環境中引入了代碼庫,也許咱們同時還引入了想法和原則。也許咱們能夠經過 《Python之禪》來表達。做者:Tim Peter。

Beautiful is better than ugly
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one—and preferably only one—obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than "right" now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea—let's do more of those!
相關文章
相關標籤/搜索