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!
相关文章
相关标签/搜索