昨天在浏览 Babel 网站时,看到它的 blog 有一篇新的文章,说 Babel 发布了新的代码支持 class 的私有属性和方法。javascript
这着实让我头脑混乱,到底在哪能够了解到最新的规范?而这些规范又是否被支持?支持到什么程度?彻底没有头绪。html
自从 ES6 规范发布以来,带来不少新的特性,而咱们在消化这些大量的知识时,ES 规范也在不停的调整和增长内容。但是咱们没有一个特定的流程和渠道来获取最新的资讯,这反而会愈来愈落后于前沿技术。java
因此在2018年的年底我整理了一下学习 ES 特性的流程和过程当中要接触到的名词。git
在20世纪60随着计算机的普及,不一样制造商在使用各自的标准开发软件,这使得为这些不一样的设备编写语言更加困难。es6
为了统一计算机领域的部分标准,欧洲知名的计算机制造商们决定城里一个协会来组建并制定章程和规则,这个协会就是「欧洲计算机制造协会」(European Computer Manufacturers Association) 简称「ECMA」github
时间到了1994年,为了体现全球化的进程,该协会更名为「欧洲信息和通讯系统标准化协会」(European association for standardizing information and communication systems) 简称 「Ecma International」,虽然名称变化了,可是由于某些历史缘由「Ecma」的商标却任然保留了下来沿用至今。正则表达式
Ecma 的历史算法
「TC39」全称「Technical Committee 39」译为「第39号技术委员会」,是 Ecma 组织架构中的一部分。是负责迭代和发展 ECMAScript 语言规范的委员会,它的成员由各个主流浏览器厂商的表明组成,一般每一年召开约 6 次会议来讨论未决提案的进展状况,会议的每一项决议必须获得大部分人的赞同,而且没有人强烈反对才能够经过。编程
TC39 主要负责:数组
ECMAScript 从 ES5 版本到 ES6 版本的发布经历了6年的时间,这带来了两个问题:
- 即便很早就完成的某项特性,也必须等到整个版本发布才能发布出来。
- 有些特性的定制会花费不少时间,那么它在实现前都必须承受很大的压力,由于没有遇上本次发布就必须再等好久,直至下一次发布。
所以 TC39 改变了过去漫长的发布流程,从 ECMAScript 2016 (ES7) 开始,每一年发布一个版本,这个版本会包含本年完成的全部功能。
那什么功能算是完成,又有什么功能能够加入议程中呢?
这就须要了解一下 TC39 的工做流程,TC39 会收集各类提案,这些提案来自 TC39 会员或注册为 TC39 撰稿人的非会员。而提案会从 0 阶段(stage 0)开始进入审核流程,它们最终会演变为 ECMAScript 的标准,或者被废弃。后面的章节中会详细介绍。
ECMAScript 是一种计算机语言的规范,是 Ecma 组织的第 262 号规范(Ecma-262)。
如今咱们也用 ESx 来指代 ECMAScript x 版本(x 表明六、201六、2017等)。
Javascript 是 ECMAScript 的一个实现。之因此用这么奇怪的方式来描述它,是由于任何人或组织均可以依照规范来实现语言。举例来讲,微软也曾经按照 ECMAScript 标准开发出一门语言叫作 JScript,这门语言本用在 IE 浏览器中。
不过在普世语境下 Javascript 和 ECMAScript 两个词已经可互换使用了,而它们也确实有很深的羁绊。
1996年8月,微软模仿 JavaScript 开发了一种相近的语言,取名为JScript(JavaScript 是 网景 的注册商标,微软不能用),首先内置于IE 3.0。网景公司面临丧失浏览器脚本语言的主导权的局面。网景公司决定将 JavaScript 提交给 Ecma,但愿 JavaScript 可以成为国际标准,以此抵抗微软。
在提交给 Ecma 之因此不叫 JavaScript,一方面是因为商标的关系,Java 是 Sun 公司的商标,根据一份受权协议,只有网景公司能够合法地使用 JavaScript 这个名字,且 JavaScript 已经被网景公司注册为商标,另外一方面也是想体现这门语言的制定者是 Ecma,不是网景,这样有利于保证这门语言的开放性和中立性。
ECMAScript® 2018 Language Specification
JavaScript 语言的历史 - JavaScript 教程 - 网道
What is language and what is dialect for computers?
1997年 Ecma 发布 「ECMAScript Language Specification, Edition 1」简称「ES1」,随后的每次发布都会在原有版本上加1。
2009年 ES5正式发布,而两年后 ES5.1发布。
又过了6年,一拖再拖的 ES6 才问世。
人们已经察觉到 Javascript 的发展速度要比其规范要快得多,一旦一个想法进入讨论阶段,浏览器就会尝试为这个特性开发原型,而社区也会开始编码实验。
因此有人建议将来的版本应该基于年份,好比用 ES2016 来标示在 2016 年结束以前敲定的任何特性规范。
尽管 ES6 被正式改名为 ES2015,但人们仍是更多的习惯称其为 ES6。不过从 ES6 之后的规范版本就正式使用年份的命名方式。
额外说一句,尚未正式发布的规范也就是还在定制阶段的特性都被称为 ESNext。
What is ESNext? Is it same as ECMAScript? - Web, Design, Programming
以前说到 TC39 会收集各类提案,并让这些提案进入审核流程,一步步推动。整个流程有5个阶段,每一个阶段都有必定的准入门槛和评定标准,咱们也不须要关心这些标准条目,咱们只须要知道一个提案到达的阶段越靠后则它被归入规范的可能性就越大。
stage-0 - 稻草人(straw-man) 基本没有准入门槛,合规的想法均可以进入这个阶段。
stage-1 - 提案(proposal) 须要肯定一个提案推动人。而后归纳问题或需求而且造成一个解决方案,列举新提案使用的方法或提供的API。讨论关键算法、概念和语义。
stage-2 - 草案(Draft) 这个阶段须要使用正式的规范语言精确地描述语法和语义
stage-3 - 候选方案(Candidate) 当草案进入这个阶段就须要进一步细化并接收用户的反馈,并描述完全部语义、语法和 API。
stage-4 - 结束(Finished) 当进入这个阶段时,提案会接受测试和验收,经过后就会进入下一个版本 ES 规范的标准之中。
每一年7月份,TC39 会正式发布当年的 ES 规范。
The TC39 process for ECMAScript features
很高兴 ECMAScript 拥抱了 GitHub 社区,经过社区自己的力量来发展自身并回馈于社区。
TC39 拥有不少仓库:
因此回归到章节的问题上来,咱们要追踪 ES6 之后的规范变化就须要在 proposals 仓库里找答案。这个仓库包含了 4 大部分,分别是 「stage-0 的提案列表」、「stage-1 到 3 的提案列表」、「结束(stage-4)的提案列表」和「非活跃(inactive)的提案列表」。
咱们在 结束的提案列表里 能找到全部 ES6 之后添加的特性,下面就列出这些特性以及发布的规范版本:
ES2016:
ES2017
ES2018
在「结束的提案列表里」还包含了一些计划在 2019 年发布的特性,因为其还未正式发布我将其概括在 ESNext 中就不在此列出了。
Release ES2016 Draft 1 · tc39/ecma262 · GitHub
proposals/finished-proposals.md · tc39/proposals · GitHub
特性的演变迅速也让 JavaScript 开发者遇到了问题,新的特性可使得编写出更高效健壮的代码,但咱们咱们的网站却要支持未提供这些新特性的旧版浏览器。在功能特性快速进化的环境下这个问题更加严峻。
上图中绿色的部分就是 ECMAScript 特性和浏览器支持的特性的差别部分,这个差别能够分红两大部分:新的 API和新的语法。
新的 API 是在原有对象的拓展,好比
Array.includes
就是对数组对象的拓展。它一般是解决一些历史遗留问题或者对经常使用代码逻辑的封装。
举例来讲,Object.is()
是一个用于检查两个值是否严格相等的新接口。===
在处理 NaN
和 -0
这样的值时会有微妙的歧义,而 Object.is()
就是用来解决这样问题的。
NaN === NaN; // false
Object.is(NaN, NaN) // true
复制代码
对于 API 的扩展带来的规范特性和浏览器特性的差别,一般都有一个被称为 polyfill 或者 shim 的模式来抹平。这两个词的意思分别是 腻子 和 垫片,从词义上来讲已经能很形象的描述它们的做用。
而 polyfill 可使用 ES5 的代码来实现这些新 API,就以 Object.is()
来讲就能够用如下代码来实现:
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}
复制代码
新的语法就好比
let
,是对功能的扩展。想要在旧浏览器中使用不支持的语法就必需要使用「转换+编译」的技术,利用专门的工具把代码转化为等价(或近似)的能够在 ES5 环境下工做的代码。
在后面的章节里会介绍用 Babel 来编译新的 ES 语法。
这里提供一个网站,专门查看兼容性表格。包含浏览器、手机端和服务器端。
简单介绍一下就是,在 某版本[1] 下的 某项特性[2] 在 某编译器或浏览器[3] 中的 兼容程度[4]。
ECMAScript 6 compatibility table
Babel 是一个 JavaScript 编译工具,专门用来编译 ECMAScript 6+ 的代码让其兼容就浏览器或运行环境。它能够转换语法、补充 API。
在圣经故事里,Babel 译为「巴别塔」,当时世界只讲同一种语言,人类决定修建一座可以通天的高塔来传播本身的名声。上帝知道了此事,担忧人类过于强大,就打乱了人类的语言,让人类不讲同语不齐同心。因而人类便分裂开来,这座塔也再也不建造了。
而这个编译器借用 Babel 之名,彷佛是想帮助人类统一 Javascript 语言呢(笑。
鉴于它在社区的普及程度很高因此本文不会介绍其具体的使用方式,而是介绍它如何配合 TC39 的工做流程。
现在的 Babel 已经发展到第7个大版本,它提供的子功能的责任划分也愈来愈清晰,对于开发者来讲须要关心两个方面:
- 把代码编译到什么程度?
- Babel 对新 ES 特性的支持程度是多少?
一般把代码编译到 ES5 的版本是最安全的,这个版本已经获得绝大多数浏览器的支持,但这会让编译后的代码文件更大。但咱们总不能在2030年还这样作,随着旧浏览器逐渐被淘汰,咱们也不须要把全部的特性都编译至 ES5 的版本。
Babel 本次更新的第7个版本,引入了 @babel/preset-env
来动态管理编译程度。若是进入这个包而不作任何配置,则会默认把代码编译到 ES5 版本。
重要的是此次 @babel/preset-env
仅包含了对已正式发布的 ES 规范的支持。若是要使用任一 stage-0 到 stage-3 中的特性或者 stage-4 中存在可是当年还未正式发布的特性,就必须安装相应的插件。
若是新特性以API的方式实现,就须要在polyfill中查看,polyfill中包含一个core-js列表专门包含了这些API。
GitHub - zloirock/core-js: Standard Library
这就是本文的最终总结了,怎样尝试使用一个新的特性。
若是你在别人的代码里或者网络上发现一个你没见过的 JS 代码语法你应该怎么办呢?
首先你应该尝试经过搜索引擎找到这种语法的正式名称。而后你就能够去 TC39 的 github 中找一下,你能够在 ecma-262 正式文档中找(不过这个文档太长了)也能够在 proposals 列表里找一下,别遗漏了 finished proposals 和 inactive proposales 列表,最终你就会找到这个语法的介绍和用例。
接着你会想看一下这个语法在不一样环境下的支持程度,因此你须要打开兼容性表格查询页面查找这个语法。
接着你也许会想尝试着编写一个用例并运行一下,那你须要在 Babel 的官网里查一下 plugins 列表里是否支持该语法,若是是新的 API 那就须要在 core-js 列表里找一下。
接着你就能够配置好 Babel 并编写用例,编译成浏览器兼容的代码,在浏览器里运行了。
TC39 on GitHub - TC39 的 GitHub 账号
ECMAScript® Language Specification - ECMAScript 最新修订版(当年准备发布的文档)
ECMAScript® Language Specification - ECMAScript 最新正式版(已发布的最新文档)
proposals - 提案列表
ECMAScript 6 compatibility table - 兼容性表格查询页面
@babel/Plugins · Babel - Babel 支持的语法插件列表
GitHub - zloirock/core-js - Babel polyfill 中支持的 API 列表
Exploring JS - 在线学习 JS 的网站做者挺牛的
ES.next News - ES 新闻订阅
写于2019年1月。
若是喜欢文章 请留下一个赞~ 若是喜欢文章 分享给更多人~
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 转载时请保留原文连接 以保证可及时获取对文章的订正和修改