如何选择合适的前端语言
===

> 过去，我一直无法相信：一个新人在三个月里可以学好前端。后来，我信了。因为三个月后，我又是一个前端的新人，我又需要重新入门前端。

前端领域好似也有一个“摩尔定律”。戈登·摩尔提出来：**积体电路上可容纳的电晶体（晶体管）数目，约每隔24个月便会增加一倍**，后来经常被引用的“18个月”。而对于前端领域来说，每隔 3-6 个月，**知识点将增加一倍**。

过去一年（即 2016 年）的每三个月（或者半年）里，前端领域不断涌现出新的知识，这些新的知识不断地在更新。这些知识点，可以源自于后台知识领域，源自于某些特定的语言，源自于新的知识理念。我们可以很轻松地找到一个例子，如前端所需要的 JavaScript 语言本身，这个语言出现了越来越多的变种。

为了完成一个复杂的前端应用，我们需要编写大量的 JavaScript 代码。但是早期版本的 JavaScript，并不适合编写中大规模的前端工程。

JavaScript 语言的变化
---

几年间，出现了 CoffeeScript、TypeScript、ClojureScript、Dart、ES6 等等的语言，他们都可以编译为 JavaScript，随后就可以在浏览器上运行。诸如 ES6，这一个新的 JavaScript 版本（现有的 JavaScript 版本，称为 ES5，即 EcmaScritp 5），则可以在最新的浏览器上运行部分或者全部的特性。

这些语言在不同的时间段里，所受到的受关注程度都是不一样的。它们都是各自的特色，在不同的时期所到的欢迎程度也是不一样的：

![JavaScript编译语言](../images/js-language-compare.jpg)

这种变化相当有趣。尽管 JavaScript 是所有主流浏览器上唯一支持的脚本语言，但是它在过去的主要用途是用来：做一些页面“特效”。它可以通过 DOM API 来操作页面上的元素，而这些元素就是显示在页面上的内容。

随后 Ajax 技术诞生了，开发人员发现可以用 JavaScript 做更多的事。JavaScript 之时，是用于在客户端上执行一些指令。而 Ajax 则可以让浏览器直接与服务端通讯。这就意味着，**你可以在浏览器间接地去操作数据库**，前端应用便因此而变得更加庞大。

### JavaScript

最初，JavaScript 是由 Netscape 雇佣 Brendan Eich 来开发的。当时他花了 10 天时间，设计出了这个语言的第一个版本。Netscape 与 Sun公司合作开发了该语言，当时 Java 语言比较火热，也因此该语言由 LiveScript 改名为 JavaScript。由设计初衷就是，**适合于新手来使用**。

此时正值浏览器大战之时，微软也推出了与 JavaScript 相似的 JScript 语言，并且内置于 IE 3.0 中。随后 IE 借助于 Windows 的威力，逐渐地占领了市场。后来，Netscape 便将 JavaScript 提交给欧洲计算机制造商协会进行标准化。标准化后的 JavaScript 便称为 ECMAScript，JavaScript 的版本也以 ECMAScript 来命名。

尽管 JavaScript 的标准由 ECMA TC39[^tc39] 委员会制定，但是要操作浏览器的元素，还需要 DOM（Document Object Model，文档对象模型）。而 DOM 是由 W3C 组织推荐的处理 XML 的标准编程接口。遗憾的是，不同浏览器对于 DOM 的支持并不一致，还存在一定的差异。在早期的浏览器里，对于 DOM、事件、Ajax 的支持存在一定的差异，因此像 jQuery 这种跨浏览器的 JavaScript 库，相当的受欢迎。

[^tc39]:  TC39 是负责 JavaScript 进化的委员会。TC39 定期举行会议，其会议是由成员公司（主要的浏览器厂商）派代表和特邀专家出席了会议。

然而，为了新手更容易上手，该语言缺少一些关键的功能，如类、模块、类型等等。在一些完备的 Web 框架里，框架本身会拥有相应的功能。

这些问题可以由各式各样的 JavaScript 库来解决。

 - 我们需要**类的功能**时，可以用 klass 库来补充；
 - 我们需要**依赖管理**时，可以用 Require.js 库来补充；
 - 我们需要**类型检查**时，可以用 tcomb 库来补充；
 - 我们需要**Promise 库来解决 callback hell**时，可以用 Bluebird 来补充。
 - 。。。

这一切看上去都很完美，但是好像有一点不对劲。

这些功能明明是这个语言应该要有的。我们却要在一个又一个的项目里，引用这些**本不需要**引用的库。

### ES6+

**作为一个程序员，如果我们觉得一个工具不顺手，那么应该造一个新的轮子**。我也喜欢去造前端的轮子，有时候是为了理解一个框架的原理，有时候则是为了创建一个更好的工具。也因此，当 JavaScript 不能满足前端工程师需求的时候，我们应该发展出一个更好的语言。于是，ES 6 就这样诞生了。

继上面的 JavaScript 的发展历史，现在主流浏览器都支持 ECMAScript 5.0 版本的标准，并且部分浏览器可以支持 ECMAScript 6。随后，ECMA 的草案以年份来命名，如 2016 年发布的 ECMAScript 草案称之为 ECMAScript 2016。而 ES 6 则对应于 ES 2015。

于是，现在：

 - 你可以使用定义函数的``默认参数``。不再需要使用 option，并 merge 这个对象了。
 - 你可以使用模板对象，使用形如`` `$ {NAME}` ``的形式来拼接模板。不再需要在一个变量切换单引号 ' 和双引号 "，并使用很多加号 + 。
 - 你可以使用箭头函数，来减少回调的代码量，并改善作用域 this 的问题。
 - 你可以使用原生的 Promises 来解决地狱式回调的问题。
 - 你还可以在 JavaScript 中使用真正的面向对象编程。
 - 。。。

在最新的 Chrome、Edge、Safari、Firefox 浏览器里，它们对于 ES6 的特性支持几乎都在 90% 以上。当我们需要在浏览器上运行 ES6 代码时，就需要使用类似于 Babel 这样的转译工具，来将代码转换为 ES5 来在普通浏览器上运行。

遗憾的是，主流的浏览器对于 ES2016+ 以及下一代的 ES.next 的支持是有限的。除此，它还有一系列需改进的语法，并不能让我觉得满意。

然后，我开始转向了 TypeScript。

### TypeScript

我开始尝试 TypeScript 的原因是，ES6 一直在变化。在 ES6 语言特性没有稳定下来的时候，我选择它作为技术栈总会存在一些风险。在这个时候，TypeScript 就成为了一个更好的选择——它创建得更早，并且语言特性稳定。而真正促使我使用 TypeScript 的契机则是，Angular 2 中采用了 TypeScript 作为开发语言。简单的来说，就是我需要用它，所以我才学 TypeScript 的。

TypeScript 与其他编译为 JavaScript 的语言初衷是类似的，为了开发大规模 JavaScript 的应用。TypeScript 是 JavaScript 的严格超集，任何现有的JavaScript程序都是合法的TypeScript程序。TypeScript 第一次对外发布是在 2012 年 10 月，而在那之前在微软的内部已经开发了两年。因此，我们可以认为它是在 2010 年左右开始开发的。

与同时期的 ES6 相比，它更加完善，并且更适合于大型应用开发。TypeScript 从其名字来看，就是 Type + Script，它是一个强类型的语言。而 ES6 只带有类型检查器，它无法保证类型是正确的。这一点在处理数据 API 时，显得非常具有优势。当接口发生一些变化时，这些 interface 就会告诉你哪些地方发生了变化。 

并且未来 TypeScript 将会和 ECMAScript 建议的标准看齐。

小结
---

除去语言本身，还有各种新的前端框架带来的变化。和其他领域（如后台，APP等等）中的框架一样，有的框架可以用于开发中大型应用，有的框架则能让我们更好地完成开发。
