一.JavaScript 的诞生
1995 年 5 月,一个叫 Brendan Eich 的人花 10 天创造了 JavaScript
二.JavaScript 语言的标准化
最初 JavaScript 语言有 2 份标准:
ECMA-262:主标准,由 ECMA 国际组织(Ecma International)负责管理
ISO/IEC 16262:第二标准,由国际标准化组织(ISO,International Organization for Standardization)和国际电子技术委员会(IEC,International Electrotechnical Commission)负责管理
出于商标版权的原因,规范标准中将这门语言称为 ECMAScript,所以原则上 JavaScript 与 ECMAScript 指的是同一个东西,但有时也会加以区分:
JavaScript:指语言及其实现
ECMAScript:指语言标准及语言版本,比如 ES6 表示语言(标准)的第 6 版
P.S.ECMAScript 中的 ECMA 取自负责管理主标准的 ECMA 国际组织,这个组织最初叫欧洲计算机制造商协会(European Computer Manufacturers Association),后来影响范围不限于欧洲,遂更名为 ECMA 国际组织(Ecma International)
三.ES 规范版本历史
ECMAScript 1(1997 年 6 月):规范第一版
ECMAScript 2(1998 年 6 月):为了同步 ISO 标准,引入了一些小更新
ECMAScript 3(1999 年 12 月):增加了正则表达式、字符串处理、控制语句(
do-while
、switch
)、异常处理(try-catch
)等众多核心特性ECMAScript 4(2008 年 7 月废除):本来是一次大规模升级(静态类型、模块、命名空间等),但跨度过大,出现了分歧,最终没能推广使用
ECMAScript 5(2009 年 12 月):变化不大,加了一些标准库特性和严格模式
ECMAScript 5.1(2011 年 6 月):又一次小更新,为了同步 ISO 标准
ECMAScript 6(2015 年 6 月):一大波更新,实现了当年 ES4 的许多设想,并正式改为按年份命名规范版本
ECMAScript 2016(2016 年 6 月):第一个年度版本,与 ES6 相比,发布周期较短,新特性也相对少些
ECMAScript 2017(2017 年 6 月):第二个年度版本
四.TC39 标准制定流程
从 ES6 来看,发版周期过长存在 2 个问题:
版本之间的时间跨度太长,提早定稿的特性要等待非常长的时间,一直等到规范正式发布(才能被实现和使用),而靠后的特性往往赶在最后发版期限之前才定稿,存在风险
语言特性的设计与实现和使用相隔太久,在实现和使用阶段才发现设计缺陷为时已晚
为此,TC39(ECMA 国际组织第 39 号技术委员会)启动了新的流程:
P.S.ECMA 国际组织设有众多技术委员会,除 TC39 ECMAScript 外,还有 TC43 Universal 3D (U3D)、TC45 Office Open XML Formats 等等,具体见Ecma template for minutes – Ecma International
主要变化在于:
ECMAScript 各项特性独立设计,历经 5 个阶段,从 Stage 0(Strawman,初稿)开始,经 Stage 1(提案)、Stage 2(草案)、Stage 3(候选提案),最后到 Stage 4(Finished,过审提案)结束
要求在后几个阶段进行原型实现和实际测试(由Test 262负责),以便在设计和实现之间形成反馈循环
ECMAScript 每年发布一版,囊括截止最后发版日期之前所有已经进入第 4 阶段的特性
所以,从 ES2016 开始(新 TC39 流程施行以来),ES 版本的概念被大大弱化了,需要关心的是特性提案处于第几阶段,只要进入第 4 阶段就已经算是标准特性了,会在下一个 6 月正式纳入标准
P.S.按照TC39 流程文档,应该是每年 7 月发版:
July: Approval of new standard by the ECMA General Assembly
但实际发版时间是每年 6 月,可能是为了纪念历史上那些 6 月发布的元老版本
五.向后兼容原则
我们发现 ES 规范每一版始终完全兼容先前的所有特性,比如 ES6 提出了let
、const
但并没有干掉var
,这是因为如果推出了不兼容的新版本,会造成一些问题:
JavaScript 引擎、IDE、构建工具都会变得臃肿,因为要支持新旧两版规范
开发者需要知道版本之间的差异
要么把现有的代码全都迁移到新版本,要么(不同项目)混用多个版本,重构会变得很麻烦
甚至要标注每段代码的所属版本,就像 ES5 手动开启严格模式一样,当时没有流行起来的一个原因是在文件或函数开头添加指令也很麻烦
为了避免这些问题,ES6 采用了一种策略叫One JavaScript:
新版本始终完全向后兼容(但偶尔可能会有轻微、不明显的清理)
旧特性不删除也不修复,而是引入更好的版本,比如
let
就是var
的改进版如果语言的某些方面有变化,只在新的语法结构内生效,即隐式选用,例如,
yield
只在generator
中才是关键字、模块和类中的所有代码都默认开启严格模式