大家好,我卡颂。
最近,Typescript v5.0 beta[1]发布,主打特性是「支持Decorators」。
有同学会疑惑,Decorators不是早就有的特性么?各种框架(比如Nest.js、Angular)早就用的飞起,ts不也早就支持了么?
之所以会有这样的疑惑,简单的说,现阶段大家使用的是老的Decorators规范,在ts中使用需要加上--experimentalDecorators flag。而ts本次更新支持的是2022年3月新的Decorator规范。
这背后更本质的原因,涉及到新的JS语法诞生的过程。今天,我们就以Decorators为例聊聊一个新的JS语法是如何诞生的。
新特性是如何产生的
所有ES语法的诞生都由国际标准组织Ecma International[2]下属的TC39(the 39nth Technical Committee)委员会负责。
这是个会员制的组织,由入会的公司、组织推举的代表组成。这些代表通常是JS开发者、学者或编程语言领域的专家(比如大家熟悉的「贺老」)。国内的360、阿里、华为、SujiTech都曾参与TC39。
委员会定期召开会议推进新的ES语法落地,这套语法落地的流程被称为The TC39 Process[3]。
值得一提的是,这套流程起源于ES2015[4],也就是大名鼎鼎的ES6。
ES2015整个版本的落地用了整整6年,包含大量新特性。我想这也是为什么提到ES新特性,很多同学首先会想到ES2015(即ES6)的原因吧。
从ES2017开始,每年都会发布新的版本,包含那些通过The TC39 Process但在上个版本没有发布的特性。
The TC39 Process
整个流程包含5个阶段,阶段0~阶段4。接下来简要介绍下各阶段的目标。
阶段0:稻草人(Strawperson)
阶段0被称为Strawperson(稻草人),由TC39成员发起,通常是提出新想法或是对未纳入正式的提案进行修改。
比如,Decorator提案[5]由「Yehuda Katz」于2014年4月10日提出。
等到这份提案到阶段3,已经2022年3月了,可想而知一个新特性的诞生有多不容易。
阶段1:提案(Proposal)
阶段1被称为Proposal(提案),此时该提案已经成为正式提案。该阶段主要提出一些具体的问题和解决方案。此时会选出一名TC39成员(通常是该提案的发起者)负责推动该提案。
继续以Decorator提案举例,他在2015年3月24日到达阶段1。
该阶段[6]指明了Decorator的:
- 设计目的
- 适用范围
比如,适用于类本身:
适用于类方法:
除此之外,还能适用于类的访问器属性(getter、setter)、对象字面量、对象的访问器属性。
- 语法
在Decorator进入阶段1的一个月后,Babel跟进了Decorator的polyfill实现。这个版本的polyfill被称为legacy。
我们可以在Babel官网看到,对于Decorator特性存在5个可选项:
不同版本的可选项对应了Decorator提案不同阶段的落地时间,由于不同阶段对Decorator规范提出了修改意见,所以相应的,Babel插件也就有了不同可选项。
类似的原因,ts中支持的Decorator也就有了不同版本,这也是造成我们开篇提到问题的本质原因。
阶段2:草稿(Draft)
阶段2被称为Draft(草稿)。在该阶段会用ES语法尽可能精确地描述提案的语法、语义和API,并提供实验性的实现。
到了该阶段,意味着提案会有很大概率出现在正式版本的ES
中。
Decorator到达阶段2的时间是2016年7月28日,距离阶段1已经过去一年多时间。
阶段3:候选人(Candidate)
阶段3被称为Candidate(候选人)。到了该阶段,提案基本已经定型,仅根据外部反馈针对关键问题进行更改。
ts在最新的v5.0 beta版本中默认支持的Decorator就是阶段3。
阶段4:完成(Finished)
阶段4被称为Finished(完成)。该提案会出现在正式的规范文档中,并在下一个版本的ES中正式支持。
总结
语言特性的推进是个蛮长的过程,最终达成的是多方博弈的结果。对于ES来说,这些博弈就体现在这4个阶段中。
还是以Decorator举例,这个特性在oop框架(比如Angular、Mobx)中是很重要的特性。Angular团队在实现Angular2时,最初考虑用AtScript实现。
而最终Angular用ts实现,其中很重要的一个原因是 —— ts团队承诺实现一些AtScript特性,尤其是Decorator。
参考资料
[1]Typescript v5.0 beta:https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/。
[2]Ecma International:https://www.ecma-international.org/。
[3]The TC39 Process:https://tc39.es/process-document/。
[4]ES2015:https://262.ecma-international.org/6.0/。
[5]Decorator提案:https://github.com/tc39/notes/blob/main/meetings/2014-04/apr-10.md。
[6]该阶段:https://github.com/wycats/javascript-decorators。