3 JavaScript 的历史和演变
3.1 JavaScript 的诞生
JavaScript 由 Brendan Eich 于 1995 年 5 月在 10 天内创建。Eich 在 Netscape 工作,并为他们的网络浏览器Netscape Navigator实现了 JavaScript。
当时的想法是用 Java 实现客户端网络的主要交互部分。JavaScript 应该是一种粘合语言,用于连接这些部分,并使 HTML 稍微更具交互性。鉴于其辅助 Java 的作用,JavaScript 必须看起来像 Java。这排除了 Perl、Python、TCL 等现有解决方案。
最初,JavaScript 的名称经过了几次更改
- 它的代号是Mocha。
- 在 Netscape Navigator 2.0 测试版(1995 年 9 月)中,它被称为LiveScript。
- 在 Netscape Navigator 2.0 beta 3(1995 年 12 月)中,它获得了最终名称,JavaScript。
3.2 JavaScript 的标准化
JavaScript 有两个标准
- ECMA-262 由 Ecma 国际托管。它是主要标准。
- ISO/IEC 16262 由国际标准化组织 (ISO) 和国际电工委员会 (IEC) 托管。这是一个次要标准。
这些标准描述的语言称为ECMAScript,而不是JavaScript。之所以选择不同的名称,是因为 Sun(现在的 Oracle)拥有后者的商标。
该组织的原始名称是ECMA,是欧洲计算机制造商协会的首字母缩写词。后来更名为Ecma 国际(“Ecma”是一个专有名词,而不是首字母缩写词),因为该组织的活动已扩展到欧洲以外。最初的全大写首字母缩写词解释了 ECMAScript 的拼写。
原则上,JavaScript 和 ECMAScript 含义相同。有时会做出以下区分
- 术语JavaScript指的是该语言及其实现。
- 术语ECMAScript指的是语言标准和语言版本。
因此,ECMAScript 6是该语言的一个版本(其第 6 版)。
3.3 ECMAScript 版本时间线
以下是 ECMAScript 版本的简要时间线
- ECMAScript 1(1997 年 6 月):标准的第一个版本。
- ECMAScript 2(1998 年 6 月):小幅更新,使 ECMA-262 与 ISO 标准保持同步。
- ECMAScript 3(1999 年 12 月):添加了许多核心功能——“[…] 正则表达式、更好的字符串处理、新的控制语句 [do-while、switch]、try/catch 异常处理、[…]”
- ECMAScript 4(2008 年 7 月放弃):本来是一次重大升级(具有静态类型、模块、命名空间等),但最终过于雄心勃勃,导致语言管理者之间产生分歧。
- ECMAScript 5(2009 年 12 月):带来了一些小的改进——一些标准库功能和严格模式。
- ECMAScript 5.1(2011 年 6 月):另一个小更新,使 Ecma 和 ISO 标准保持同步。
- ECMAScript 6(2015 年 6 月):一次重大更新,兑现了 ECMAScript 4 的许多承诺。此版本是第一个官方名称——ECMAScript 2015——基于出版年份的版本。
- ECMAScript 2016(2016 年 6 月):第一个年度版本。与大型 ES6 相比,更短的发布周期导致新功能更少。
- ECMAScript 2017(2017 年 6 月)。第二个年度版本。
- 后续的 ECMAScript 版本(ES2018 等)总是在 6 月获得批准。
3.4 Ecma 技术委员会 39 (TC39)
TC39 是发展 JavaScript 的委员会。严格来说,其成员是公司:Adobe、Apple、Facebook、Google、Microsoft、Mozilla、Opera、Twitter 等。也就是说,通常是激烈竞争对手的公司正在为语言的利益而共同努力。
TC39 每两个月举行一次会议,成员任命的代表和受邀专家参加。这些会议的纪要公开在GitHub 存储库中。
3.5 TC39 流程
在 ECMAScript 6 中,当时使用的发布过程存在两个明显的问题
为了应对这些问题,TC39 制定了新的TC39 流程
- ECMAScript 功能是独立设计的,并经历多个阶段,从 0(“稻草人”)开始,到 4(“完成”)结束。
- 特别是后期阶段需要原型实现和实际测试,从而导致设计和实现之间的反馈循环。
- ECMAScript 版本每年发布一次,包括在发布截止日期之前达到第 4 阶段的所有功能。
结果:更小、增量的版本,其功能已经过现场测试。图 1说明了 TC39 流程。
ES2016 是第一个根据 TC39 流程设计的 ECMAScript 版本。
3.5.1 提示:从单个功能和阶段的角度思考,而不是 ECMAScript 版本
直到并包括 ES6,最常见的做法是从 ECMAScript 版本的角度考虑 JavaScript——例如,“此浏览器是否支持 ES6?”
从 ES2016 开始,最好从单个功能的角度考虑:一旦某个功能达到第 4 阶段,您就可以安全地使用它(如果您的目标 JavaScript 引擎支持它)。您不必等到下一个 ECMAScript 版本。
3.6 常见问题解答:TC39 流程
3.6.1 我喜欢的提议功能进展如何?
如果您想知道各种提议功能处于哪些阶段,请参阅GitHub 存储库proposals
。
3.6.2 是否有 ECMAScript 功能的官方列表?
是的,TC39 存储库列出了已完成的提案,并提到了它们是在哪个 ECMAScript 版本中引入的。
3.7 JavaScript 的演变:不要破坏网络
偶尔会出现的一个想法是通过删除旧功能和怪癖来清理 JavaScript。虽然这个想法的吸引力是显而易见的,但它也有很大的缺点。
假设我们创建了一个不向后兼容的新版本 JavaScript,并修复了它的所有缺陷。结果,我们会遇到以下问题
- JavaScript 引擎变得臃肿:它们需要同时支持旧版本和新版本。IDE 和构建工具等工具也是如此。
- 程序员需要了解并不断意识到版本之间的差异。
- 您可以将所有现有代码库迁移到新版本(这可能需要大量工作)。或者,您可以混合使用多个版本,而重构会变得更加困难,因为您无法在不更改代码的情况下在版本之间移动代码。
- 您必须以某种方式为每段代码指定其编写的版本——无论是文件还是嵌入在网页中的代码。每个可能的解决方案都有其优缺点。例如,严格模式是 ES5 的一个稍微干净的版本。它没有像应有的那样流行的原因之一是:通过文件或函数开头的指令选择加入很麻烦。
那么解决方案是什么?我们能否鱼与熊掌兼得?为 ES6 选择的方法称为“一个 JavaScript”
- 新版本始终完全向后兼容(但偶尔可能会有一些细微的、几乎察觉不到的清理)。
- 旧功能不会被删除或修复。相反,会引入更好的版本。一个例子是通过
let
声明变量——它是var
的改进版本。
- 如果语言的某些方面发生了变化,则会在新的语法结构中完成。也就是说,您是隐式选择加入的。例如,
yield
只是生成器(在 ES6 中引入)中的一个关键字。模块和类(都在 ES6 中引入)中的所有代码都隐式处于严格模式。