ES5,ES2015(原名 ES6 )和 TypeScript 之间有什么不同?我们应该学习和使用哪一个?
首先,让我们为讨论这些建立一个基础。TypeScript 是 JavaScript 的超集。ES2015 是 ES5 的改进。知道关系可以让我们更容易学习他们。
我们想要理解他们之间的差异,首先我们就必须理解他们为什么存在。 我们从 ES5 开始。
ES5
我们大多数人已经用了 ES5 好多年了。函数式编程在它这儿最棒,或者说最糟糕,这要取决于你如何看待它了。我个人喜爱用ES5编程。所有的现代浏览器都对它进行了支持。它极其灵活,但这也会产生很多能将应用推到坑里的因素。作用于、闭包、IIFE以及良好的防御式逻辑,这些对于确保我们的ES5代码不翻船都是必要的。尽管如此,其灵活性还是我们要依靠的一份力量。
也许ES5给我们带来的最大的问题就是在开发时定位问题的困难。ES5 因其复杂性而缺少工具,充其量就是有工具能解析如何检查ES5的某些关键点。我们想要知道的是在另外一个文件中的对象包含了哪些属性, 一个函数中的一个无效参数可能是什么, 或者让我们知道在什么时候我们在一个不正常的作用域里面使用了一个变量。ES5 让这些事情对于开发者和工具而言都困难了起来。
ES6/E2015 飞跃前进
ES2015 是从 ES5的一个巨大飞跃。它给JavaScript增加了大量的功能特性。这些功能特性解决一些问题,这些问题曾使得ES5编程成为一项挑战。它们是可选的,因此我们可以在ES2015中继续有效的使用 ES5 (包括函数)。
这里所见是 Luke Hoban 提供的 ES2015的一些功能特性的参考。完整的列表可以在这份文档中查看。 - arrows - classes -增强的对象文本 - 模板字符串 - 析构 - default + rest + spread - let + const - 迭代器 + for..of - generators - unicode - 模块 - 模块加载器 - map + set + weakmap + weakset - 代理 - 符号 - 内置插件式的可子类化 - 承诺 - math + number + string + array + 对象 API - 二进制和八进制文本 - 反射api - 尾调用
这是对于ES5的一个巨大飞跃,而现代的浏览器都在争先实现所有的这些功能特性。这份图表展示了浏览器当前对于ES2015的兼容程度。
Node.js 是针对V8引擎的现代版本而构建的。根据其文档来看,Node 已经对 ES2015的许多东西进行了实现。
Node 4.x 给自己打上了 LTS 标签,定位于长期支持的版本。 LTS 标签显示了他们的产品发布规律。所有偶数的主版本专注于稳定性和安全性。所有奇数的主版本 (例如 5.x) 则归入短期支持 (STS) 的版本, 专注于积极地拓展和更高频率的更新。简言之,我的建议是仍将node4用于生产环境的开发中,而将node5用于研究可能会在未来的LTS版本中存在的功能特性。你可以读一读这里的《node版本官方指南》。
回到 ES2015, 现在我们已经拥有了数量惊人的功能可以选择用来编写代码。
开发者如何看待 ES2015?
我们也许想要知道谁可能会对ES2015感兴趣,还有谁并不感兴趣。许多的ES5都深谙这门语言的利弊。在JavaScript领域混迹了十多年以后,我们可能会感觉ES5用起来非常舒适。如果没有明白其中的价值,一旦我们已经掌握了一门语言,要找个理由跳转到一个新的版本就可能有点困难了。我们会得到什么?我们要解决什么问题呢? 这就是我们自然而然会生出的想法。一旦我们认定迁移到ES2015有利可图, 那么就会做出迁移的决定。
也有许多ES5开发者都等不及要使用 ES2015 了。关键是很多曾今使用ES5的人已经在用到ES2015了,而更多的人则仍然在决定中踯躅不前。
现如今 JavaScript 开发者有许许多多,而且还有更多人在进入这个领域。我认为现在正考虑学习JavaScript以及那些仍在在学习的人的数量,将会比目前正在使用它的人要少。 JavaScript 正处在发展之中,而并不是每个人都会有一个成熟的 ES5 开发背景。许多人都来自于Java和C#已经其它流行的语言和框架。这些的许多都已经拥有了 ES2015最近引入的功能特性,并且用了都好几年了。这使得ES2015对于他们而言比起ES5来说更容易过渡。而现在也是个好时候,因为许多现代浏览器以及 Node 都在支持着ES2015。
因而我们有许多人,都拥有着不同的背景,却都会走上 ES2015 (或者更高版本) 的迁移之路。
支持 ES5 的浏览器
我们如何才可以在还不支持ES2015的浏览器中运行ES2015? 我们可以使用像 Babel 这样的工具,用 ES2015 编写代码,然后将代码转换成 ES5。Babel 使得编写 ES2015 变得简单 (未来的ES2016以及更高版本也不在话下),然后仍将代码向下编译成老版本的JavaScript。相当的酷!
TypeScript
TypeScript 适合用在哪里呢? 甚至于我们是否应该去使用它呢?
首先,我觉得这个名字就有点让人望而却步。TypeScript中的Type这个词表明我们会拥有类型。这些类型是可选的,因此我们并不是非得用上它们不可。不相信我? 当你尝试将ES5代码复制到 TypeScript playground 中去的时候。看看,天啦! 不需要任何类型! 所以我们是不是可以选择性的它 Type?Script 或者 [Type]Script 呢? 开个玩笑,类型知识TypeScript一块而已。也许更好的名称就是简单的 ES+。
让我们回头来回顾一下之前我曾提过的问题,许多开发者在编写JavaScript的时候都会遇到: 在开发时识别错误的困难。
如果在编写它们的时候就我们可以识别出作用域问题会如何呢? 如果可以在我们的工具中通过红色的下划线识别不匹配的参数会如何呢? 如果编辑器和IDE可以告知我们在不正当的使用了别人或者我们自己的代码的时候会告诉我们,会如何呢?这些都是我们通常要依赖工具的地方。
尽早地识别出问题
无论我们使用的是 Atom, VS Code, Visual Studio, Web Storm, 还是 Sublime Text,我们所要享受的都是其多得有点过剩的固有功能或者可供我们选择的工具扩展,是它们在帮助我们较快的写出更好的代码。这些工具应该(而且能够)对尽早识别出问题起到有所帮助。
当我们编写代码时候,如果能马上找到一个问题的话,就会更加有意思,于是我们就可以就地解决它 … 或者在早上5点钟被叫醒,因为恰好在那时候触发了我们隐藏的bug而导致业务中断,生产环境爆出问题?5点那个时候我宁愿跟我的家人待在一起 :)
今天的这些工具在试图帮助我们识别问题,而它们的工作确实令人钦佩。不过如果我们可以给它们更多一点点的帮助会如何呢? 如果我们赋予它们跟今天其它像C#和Java这样的语言相同的类型的帮助会如何呢? 那这些工具就确实能尽早而且频繁的帮助我们识别出问题来。
这就是 TypeScript 的用武之地。
TypeScript 的价值并不在于编写更少的代码,其价值在于编写更加安全的代码。从长远看来,它能帮助我们利用其工具识别问题并自动填充参数、属性、函数以及更多东西(通常被成为自动补全和智能感知),从而更有效率的编写出代码。
你可以在其playground中体验TypeScript。
ES+
我开玩笑说 TypeScript 应该被叫做 ES+, 而当我们更近一点观察它的时候,还确实是这样的。
那么 TypeScript 在 ES2015 之外还提供了什么呢? 我将专注于三个我所认为增加了最大价值的方面 :
1.类型
2.接口
3.未来的 ES2016+ 特性 (比如注解/装饰器以及异步/等待)
TypeScript 就是 ES 机上像这样的一些特性。
类型和接口对于提供那些需要在我们敲写代码的时候就能识别出问题的功能有帮助。有了这些功能特性,编辑器就不需要去猜测我们是否在正常地使用一个函数。错误信息对于工具而言足够明确,足以让它们向我们亮起红灯,那样我们就可以立即对问题进行修复。在某些情况下,这些工具也能在推荐和重构上帮助到我们!
TypeScript 有望成为前瞻性的思维。它有助于我们提前商榷未来ECMAScript中出现的功能特性。例如像装饰器 (在 Angular 2 中有被用到) 以及异步/等待 (一种可以让C#中的异步编程更加轻松的流行技术)这样的技术。装饰器现在在TypeScript中已经可以使用了,而据 《TypeScript路线图》 异步/等待很快就会在 2.0 版本中推出。
TypeScript 是否会偏离 JavaScript 的方向?
在 TypeScript 网站的头版页面 顶部,我们找到了这样一条声明:
TypeScript 是JavaScript 类型化子集,它会被编译成原生的JavaScript。
这是非常重要的。TypeScript 并不是一种捷径语言。它不会偏离 JavaScript,不会将我们带去另外一个方向。它的目的是让我们可以在今天就能使用到将会在未来的JavaScript版本中出现的功能特性, 并提供一个更好且更加安全的体验。
为什么不就使用 ES2015 得了?
这是一个很棒的选择 ! 学习 ES2015 是从 ES5 的一个很大的进步。一旦你掌握了 ES2015, 我敢说从此 TypeScript 就是只是非常小的一步。因此回头我会建议,一旦你学习了 ES2015, 要尝试一下 TypeScript 并利用好它的工具。
就业情况怎么样?
学些 ES2015 或者 TypeScript 会对我的就业产生不良影响吗? 当然不会。不过这也并不意味着你不去理解ES5。今天 ES5 无所不在。不过它终有没落的一天,但还有那么多 ES5 在那儿,而理解这门语言对于理解ES2015和TypeScript帮助我们解决了什么毕竟是有好处的。另外我们也能够利用ES5的知识来使用浏览器中的源码映射对问题进行调试。
紧跟新兴技术的脚步
很长一段时间里我们都不需要什么转译器(transpiler)。Web使用的是JavaScript,而大多数编写ES3和ES5的家伙都在用jQuery来处理跨浏览器问题。当ES5到来时,并没有发生太多的变化。多年来从事着 Web开发,我们已经拥有了一套稳定的大多数浏览器都能理解的JavaScript功能特性。如果哪里出了问题,我们会使用想 es5-shim.js 甚至jQuery来处理它们。但时代在变。
Web的步伐现在很快。新的标准不断涌向。像Angular 2, Rx.js, React, 以及 Aurelia 这样的库在推动这 Web向前发展。更多的开发者正在通过 web和Node.js进入JavaScript这个领域。
ECMAScript 团队现在采纳了一种新的命名方式,以年份作为标识,区分语言的版本。不会有ES6了,现在我们叫它ES2015。而下一个版本则被指向 ES2016。其意图就是让新的功能特性更加频繁地加入到JavaScript中去。对于所有的浏览器而言,从桌面到移动端都采纳这一套标准,是需要花点时间的。
整个这些意味着什么呢? 正当我们拥有了支持ES2015的浏览器的时候, ES2016 可能就出来了。 如果没有其它帮助,而我们又想要在所有的浏览器上都用上新的功能特性,就可能会有点可怕了! 除非我们有办法可以利用今天的新的功能特性,并支持我们需要支持的浏览器。
这就是为甚转译器的出现在今天的Web领域如此重要的原因。TypeScript 和 Babel (转译领域的主要玩家) 都在其出现在浏览器之前就已经支持ES2015了。它们都计划要支持(并且已经在某些情况下这样做了) ES2016 的功能特性。这些工具就是我们如何一边继续向前推进,又不会把我们的客户落下,这个问题的答案。
我们是如何反编译(Transpile)的?
我们可以使用类似 Gulp,Grunt,WebPack,SystemJS 和 JSPM 这些工具反编译成 Babel 或者 TypeScript。很多编辑器直接连接到这些任务为我们的代码进行反编译。现在,很多 IDE 都支持通过点击一个按钮自动化反编译。我们甚至可以在命令行中使用 TypeScript,并可以查看我们的文件并进行反编译。
总之,我们的代码都有很多种方式可以进行反编译。
这意味着什么
实际上,在技术上的改变会改变我们在职业上的选择。有时候,技术上发生的改变远远快于我们的吸收速度。这就是为什么工具是重要的,因为它可以帮助我们吸收,就像 TypeScript 和 Babel 之于 ES2015(更高版本)。在这个例子中,我们使用技术来跟上技术。这看起来像是一个悖论,但是它的核心就是要我们有效使用时间。