烟雾的方块艺术 —MattysFlicks —(CC BY 2.0)javascript
注意:这是从基础学习函数式编程和使用 JavaScript ES6+ 撰写软件的第二部分。保持关注,接下来还有不少!
第一篇 | 第三篇 >html
忘掉你认为知道的关于 JavaScript 的一切,用初学者的眼光去看待它。为了帮助你作到这一点,咱们将会从头复习一下 JavaScript 的基础,就像你与其还没有谋面同样。若是你是初学者,那你就很幸运了。最终从零开始探索 ES6 和函数式编程!但愿全部的概念都被解释清楚 — 但不要太依赖于此。前端
若是你是已经熟悉 JavaScript 或者纯函数式语言的老开发者了,也许你会认为 JavaScript 是探索函数式编程有趣的选择。把这些想法放在一边,用更开放的思想接触它,你会发现 JavaScript 编程更高层次的东西。一些你历来不知道的东西。java
因为这个被称为“组合式软件”,同时函数式编程是明显的构建软件的方法(使用函数组合,高阶函数等等),你也许想知道为何我不用 Haskell、ClojureScript,或者 Elm,而是 JavaScript。node
JavaScript 有函数式编程所须要的最重要的特性:react
x => x * 2
是 JavaScript 中有效的函数表达式。简洁的 lambda 语法使得高阶函数变的简单。add2(1)(2)
中,1
是 add2(1)
返回的函数中的固定参数。JavaScript 是多范式语言,意味着它支持多种风格的编程。其余被 JavaScript 支持的风格包括过程式(命令式)编程(好比 C),把函数看做能够被重复调用和组织的子程序指令;面向对象编程,对象— 而不是函数— 做为初始构造块;固然,还有函数式编程。多范式编程语言的劣性在于命令式和面向对象每每意味着全部东西都是可变的。android
可变性指的是数据结构上的变化。好比:ios
const foo = {
bar: 'baz'
};
foo.bar = 'qux'; // 改变复制代码
对象一般须要可变性以便于被方法更新值,在命令式的语言中,大部分的数据结构可变以便于数组和对象的高效操做。git
下面是一些函数式语言拥有可是 JavaScript 没有的特性:github
for
、while
、do
这类循环语句。纯粹性: 在 JavaScript 中,纯粹性由约定来达成,若是你不是使用纯函数来构成你的大多数应用,那么你就不是在进行函数式风格的编程。很不幸,在 JavaScript 中,你很容易就会不当心建立和使用一些不纯的函数。
不可变性: 在纯函数式语言中,不可变性一般是强制的,JavaScript 缺乏函数式语言中高效的、基于 trie 树的数据结构,可是你可使用一些库,包括 Immutable.js 和 Mori,由衷指望将来的 ECMAScript 规范版本能够拥抱不可变数据结构。
有一些迹象带来了但愿,好比说在 ES6 中添加了 const
关键字,const
声明的变量不能被从新赋值,重要的是要理解 const
所声明的值并非不可改变的。
const
声明的对象不能被从新声明为新的对象,可是对象的属性倒是可变的,JavaScript 有 freeze()
对象的能力,可是这些对象只能在根实例上被冻结,意味着嵌套着的对象仍是能够改变它的属性。换句话说,在 JavaScript 规范中看到真正的不可变还有很长的路要走。
递归: JavaScript 技术上支持递归,可是大多数函数式语言都有尾部调用优化的特性,尾部调用优化是一个容许递归的函数重用堆栈帧来递归调用的特性。
没有尾部调用优化,一个调用的栈极可能没有边界致使堆栈溢出。JavaScript 在 ES6 规范中有一个有限的尾调用优化。不幸的是,只有一个主要的浏览器引擎支持它,这个优化被部分应用随后从 Babel(最流行的 JavaScript 编译器,在旧的浏览器中被用来把 ES6 编译到 ES5) 中移除。
最重要的事实:如今使用递归来做为大的迭代还不是很安全 — 即便你很当心的调用尾部的函数。
一个纯粹主义者会告诉你 JavaScript 的可变性是它的重大缺点,这是事实。可是,引发的反作用和改变有时候颇有用。事实上,不可能在规避全部反作用的状况下开发有用的现代应用。纯函数式语言好比说 Haskell 使用反作用,使用 monads 包将有反作用的函数假装成纯函数,从而使程序保持纯净,尽管用 Monads 所带来的反作用是不纯净的。
Monads 的问题是,尽管它的使用很简单,可是对一个不是很熟悉它的人解释清楚它有点像“对牛谈琴”。
“Monad说白了不过就是自函子范畴上的一个幺半群而已,这有什么难以理解的?” ~James Iry 所引用 Philip Wadler 的话,解释一个 Saunders Mac Lane 说过的名言。“编程语言简要、不完整之黑历史”
典型的,这是在调侃这有趣的一点。在上面的引用中,关于 Monads 的解释相比最初的有了很大的简化,原来是下面这样:
“
X
中的 monad 是其 endofunctor 范畴的幺半群,生成 endofunctor 和被 endofunctor 单位 set 组合所代替的X
” ~ Saunders Mac Lane。 "Categories for the Working Mathematician"
尽管这样,在个人观点看来,惧怕 Monads 是没有必要的,学习 Monads 最好的方法不是去读关于它的一堆书和博客,而是马上去使用它。对于大部分的函数式编程语言来讲,晦涩的学术词汇比它实际概念难的多,相信我,你没必要经过了解 Saunders Mac Lane 来了解函数式编程。
尽管它不是对全部的编程风格都绝对完美,JavaScript 无疑是做为适应各类编程风格和背景的人的通用编程语言被设计出来的。
根据 Brendan Eric 所言,在一开始的时候,网景公司就有意适应两类开发者:
“...写组件的,好比说 C++ 或者 Java;写脚本的、业余的和爱好者,好比直接写嵌在 HTML 里的代码的。”
原本,网景公司的意向是支持两种不一样的语言,同时脚本语言大体要像 Scheme (一个 Lisp 的方言),并且,Brendan Eich:
“我被招聘到网景公司,目的是在浏览器中 作一些 Scheme”。
JavaScript 应当是一门新的语言:
“上级工程管理的命令是这门语言应当像 Java,这就排除了 Perl,Python,和 Tcl,以及 Scheme。”
因此,Brendan Eich 最初脑子里的想法是:
它最终更像是个大杂烩:
“我不骄傲,但我很高兴我选择了 Scheme 的一类函数和 Self(尽管奇怪)的原型做为主要的元素。”因为 Java 的影响,特别是 y2k 的 Date 问题以及对象的区别(好比 string 和 String),就不幸了。”
我列出了这些 “很差的” 的类 Java 特性,最后整理成 JavaScript:
new
关键子,跟工厂函数有着不一样的调用和使用语义。class
的关键字和单一父类 extends
做为最初的继承机制。class
看做是它的静态类型(实际并不是如此)。个人意见:永远避免使用这些东西。
很幸运 JavaScript 成为了这样厉害的语言,由于事实上证实脚本的方式赢了那些创建在“组件”上的方式(如今,Java、Flash、和 ActiveX 扩展已经不被大部分安装的浏览器支持)。
咱们最终创做了一个直接被浏览器支持的语言:JavaScript。
那意味着浏览器能够减小臃肿和问题,由于它们如今只须要支持一种语言:JavaScript。你也许认为 WebAssembly 是例外,可是 WebAssembly 设计之初的目的是使用兼容的抽象语法树来共享 JavaScript 的语言绑定(AST)。事实上,最先的把 WebAssembly 编译成 JavaScript 的子集的示范是 ASM.js。
做为 web 平台惟一的通用标准编程语言,JavaScript 在软件历史潮流中乘风直上:
App 吞食世界, web 吞食 app, 同时 JavaScript 吞食 web。
根据多个平台调查,JavaScript 是目前世界上最流行的语言。
JavaScript 并非函数式编程的理想化工具,可是它倒是为大型的分布式的团队开发大型应用的好工具,由于不一样的团队对于如何构建一个应用或许有不一样的见解。
一些团队致力于脚本化,那么命令式的编程就特别有用,另一些更精于抽象架构,那么一点保留的面向对象方法也许不失为坏。还有一些拥抱函数式编程,使用纯函数来确保稳定性、可测试性和项目状态管理以便减小用户的反馈。团队里的这些人可使用相同的语言,意味着他们能够更好的交换想法,互相学习和在其余人的基础上更进一步的开发。
在 JavaScript 中,全部这些想法能够共存,这样就让更多的人开始拥抱 JavaScript,而后就产生了世界上最大的开源包管理器 (2017 年 2 月),npm。
JavaScript 的真正优点在于其生态系统中的思想和用户的多样性。它也许不是纯函数式编程最理想的语言,但它是你能够想象的工做在不一样平台的人共同合做的理想语言,好比说 Java、Lisp 或者 C。JavaScript 也许并不对有这些背景的用户彻底友好,可是这些人很乐意学习这门语言并迅速投入生产。
我赞成 JavaScript 并非对函数式编程者最好的语言。可是,没有任何其余语言能够声称他们能够被全部人使用,同时正如 ES6 所述:JavaScript 能够知足到更与喜欢函数式编程的人的须要,同时也愈来愈好。相比于抛弃 JavaScript 和世界上几乎每家公司都使用的使人难以置信的生态系统,为何不拥抱它,把它变成一个更适合软件组合化的语言?
如今,JavaScript 已是一门足够优秀的函数式编程语言,意味着人们可使用 JavaScript 的函数式编程方法来构造不少有趣的和有用的东西。Netflix(和其余使用 Angular 2+ 的应用)使用基于 RxJS 的函数式功能。Facebook在 React 中使用纯函数、高阶函数和高级组件来开发 Facebook 和 Instagram,PayPal、KhanAcademy、和Flipkart使用 Redux 来进行状态管理。
它们并不孤单:Angular、React、Redux 和 Lodash 是 JavaScript 生态系统中主要的框架和库,同时它们都被函数式编程很深的影响到— 在 Lodash 和 Redux 中,明确地表达是为了在实际的 JavaScript 应用中使用函数式编程模式。
“为何是 JavaScript?”由于 JavaScript 是实际上大多数公司开发真实的软件所使用的语言。不管你对它是爱是恨,JavaScript 已经取代了 Lisp 这个数十年来 “最受欢迎的函数式编程语言”。事实上,Haskell 更适合当今函数式编程概念的标准,可是人们并不使用它来开发实际应用。
在任什么时候候,在美国都有近十万的 JavaScript 工做需求,世界其余地方也有数十万的量。学习 Haskell 能够帮助你很好的学习函数式编程,但学习 JavaScript 将会教会你在实际工做中开发应用。
App 正在吞食世界, web 正在吞食 app, 同时 JavaScript 正在吞食 web。
想更多的学习 JavaScript 的函数式编程?
Learn JavaScript with Eric Elliott,什么,你还不是其中之一,out 了!
Eric Elliott 是 “Programming JavaScript Applications” (O’Reilly) 和 “Learn JavaScript with Eric Elliott” 的做者。他曾效力于 Adobe Systems, Zumba Fitness, he Wall Street Journal, ESPN, BBC, and top recording artists including Usher, Frank Ocean, Metallica 和其余一些公司。
他和她的老婆(很漂亮)大部分时间都在旧金山湾区里。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、React、前端、后端、产品、设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划。