当前位置: 代码迷 >> 综合 >> JavaScirpt 与 ECMAScript 的关系
  详细解决方案

JavaScirpt 与 ECMAScript 的关系

热度:68   发布时间:2023-10-10 07:38:27.0

很多人在深入了解 JavaScript 的时候会看到类似这样的一段文字:

JavaScirpt 分为三个部分:ECMAScript、DOM、BOM。

再继续深入调查的话还会了解到 ECMAScript 是一个语言标准。
如此说来,JavaScript 和 ECMAScript 有着不浅的关系,但是它们之间的关系却又不那么好让人理解。所以,这篇文章就来好好梳理一下两者之间的关系。
注意:本文仅代表作者个人观点,只是以作者的理解来阐述。欢迎指正拙见中的错误。

JavaScript 的诞生

JavaScript 诞生于 1995 年,其最初的设计目的是用于解决网页过于缺乏互动性的问题。因为当时的互联网网速不像现在这个时代这么快,而网页却日益变得复杂与庞大。其中最为突出的糟糕点是在网页的表单验证上,用户必须填完整个表单并提交验证后才能发现表单填写中存在的问题。让用户能在表单填写途中就发现问题,让网页更具有互动性等等,成为了网页开发中的需求。于是当时的网景公司(Netscape)便开发了一门名为“Mocha”的脚本语言,后来又改名为了“LiveScript”。而就在 LiveScript 即将发行前,网景公司为了让其能获得更高的关注度,便将其改名为了“JavaScript”。

ECMAScript 标准的诞生

在 JavaScript 发行的前后,另外两家公司也在为解决网页缺乏互动性的问题上开发了两门语言,JavaScript 并不是在解决这一问题上的唯一探索者。先来介绍一下这另外两位。
ScriptEase:在 1992 年左右,一家称作“Nombas”的公司开发了一种叫做“C-minus-minus”(简称 Cmm)的嵌入式脚本语言,Cmm 的理念是让其足以取代宏操作(Marco),并且与 C 语言足够相似,但是这门语言被捆绑在了一个名为“CEnvi”的共享软件中,即要使用 Cmm 需要依赖 CEnvi 。后来,由于 Cmm(C减减)这个名字带有一定的负面意义,Nombas 将其改名为了“ScriptEase”,而当网景公司的 Netscape Navigator 崭露头角时,Nombas 开发了一个可以嵌入网页中的 CEnvi 的版本,也就代表了 ScriptEase 可以被使用在网页中了。
JScript:恰巧在 JavaScript 发布了 1.1 版的时候,微软决定进军浏览器,发布了 IE 3.0 并搭载了一个 JavaScript 的克隆版,叫做“JScript”。JScript 并不是完全模仿 JavaScript,在 ECMAScript 标准发布前后 JScript 曾在许多方面于 JavaScript 之前率先设计发布了自己的实现并设计了一些自己独有的特性和语法,甚至后来 JavaScript 还引入了一部分 JScript 的特性和语法。但是 JScript 现在已经被微软遗弃了,JScript 也不再更新。
在微软进入了浏览器领域后,ScriptEase、JavaScript、JScript,三种 JavaScript 的原始版本同时存在,三者极为相似,然而却又不完全兼容,并且最重要的是,没有一个标准来统一这类脚本语言的语法或特性。在这种情形下 JavaScript 1.1 作为一个草案被提交给欧洲计算机制造商协会(ECMA),通过 ECMA 第 39 技术委员会(TC39)来“标准化一个通用的、跨平台的、中立于厂商的脚本语言的语法和语义”。由来自网景公司、Sun、微软、Borland 和其他一些对脚本编程感兴趣的公司的程序员组成的 TC39 推出了 ECMA-262 标准,该标准定义了名为“ECMAScript”的全新脚本语言。
由此可以说,ECMAScript 其实是从 JavaScript 中独立出来的一套语言标准。

ECMAScript 在 JavaScript 中的地位

深入了解过 JavaScript 的人应该都了解过一句话:

JavaScript 是 ECMAScript 的一种实现与扩展。

既然 JavaScript 是用来实现 ECMAScript 的,那么 ECMAScript 必然是 JavaScript 的根基。ECMAScript 标准描述了这门语言的语法和基本对象,那么这一部分就是 JavaScript 里必须要有的东西。而语法是一门语言里最核心的部分,在这一层意义上,ECMAScript 就像是 JavaScript 的模子,对其起指导作用。每当 ECMAScript 标准的新版本(ES6、ES7、ES2019)发布之后,各大 JavaScript 引擎的开发者便会按照这个新版本标准更新自家的引擎,为其添加新标准中的特性。

JavaScript 与 ECMAScript 的关系

在上文我提到过:

JavaScirpt 分为三个部分:ECMAScript、DOM、BOM。

除了 ECMAScript 标准里的东西,JavaScript 还有 DOM(文档对象模型)、BOM(浏览器对象模型),这两者分别定义了脚本用来操作文档和浏览器的对象,如 document、Navigator 等。这两样东西是直接存在于 JavaScript 的脚本的运行环境中的,并且以 ECMAScript 标准中的对象的形式供脚本访问和操作,但是单纯的 ECMAScript 标准里是没有这些东西的,这是属于 JavaScript 中自己扩展的那一部分。在这种层面上来看 JavaScript 更像是 ECMAScript 标准所规定的脚本的一种运行时环境,但是 DOM 和 BOM 却又明确地存在于 JavaScript 的标准中,定义了其上的各种对象与用法。所以总结起来,JavaScript 的本质是 ECMAScript,但又在其基础上增添了许多自己的东西,形成了一个整体。JavaScript 是 ECMAScript 的一种实现与扩展。

你或许听说过 Node.js,它的介绍说自己是一个 JavaScript 运行环境。但于我而言,我更喜欢叫它“ECMAScript 运行环境”。因为,正如我上文提到:BOM、DOM 是属于浏览器里的“JavaScript”的,说的更直白些,那是浏览器提供的“API(接口)”,是浏览器把操作自己、操作网页的方法放进了 ECMAScript 的运行空间中,这才构成了 JavaScript。离开了浏览器,没有了 BOM、DOM 这两个属于 JavaScript 的灵魂,也就谈不上是 JavaScript 了。不过这些其实有点属于杠精之谈,对于早已自成一体的 JavaScript 来说,什么属于什么根本不重要。

区分 JavaScript 中的各个部分

虽说不重要,但认识一下哪些东西是 ECMAScript 的,哪些又是 BOM 和 DOM 的,有时还是会有用的。

ECMAScript 自己的东西说少不少,说多不多。

  • 语法(关键字、保留字、语句写法、定义方式、抽象概念)
  • 基本数据类型(number、boolean、string、symbol、bigint、null、undefined、Object)
  • 数据对象类型(Array、Map、Set、WeakMap、WeakSet)
  • 基本数据类型的包装类(Number、Boolean、String、Symbol、BigInt)
  • 功能对象类型(Function、Date、RegExp、Error、Promise、Blob、Generator)
  • 数学方法(Math)
  • Proxy
  • Reflect
  • 抽象控制逻辑(GeneratorFunction、AsyncFunction)
  • TypedArray 族系
  • 视图数据结构及其接口(ArrayBuffer、SharedArrayBuffer、Atomics、DataView)
  • JSON
  • 全局对象
  • 全局常量
  • 全局变量
  • 全局函数(eval、parseInt、parseFloat、isFinite、isNaN)
  • 严格模式
  • 模块

上面的东西,只要是声称自己是 ECMAScript / JavaScript 的,都能用。不过前提是它参照的是最新版的规范,就像许多其他语言一样,总有人还在用着旧版本。ECMAScript 经历了许多变化,添加了新的特性,也删除了一些特性,上面列出来的东西说不定哪一天也会过时。

浏览器里面能用到的除去上面的,就属于 BOM 和 DOM 了。
由于这些内容数量众多,不能一一列举,所以就概述了。

  • 文档对象类型(最常用的是 HTML 文档,对应的类是 HTMLDocument。同时 JavaScript 天然支持多种文档,HTML 脱胎自 XML,所以 JavaScript 也支持 XML 文档,对应的类就是 XMLDocument。虽然 JavaScript 没有内置太多其他类型的文档对象,但支持了 XML,也就很容易操作基于 XML 的其他文档类型。这两者都继承自 Document 类。)
  • 浏览器对象类型(Navigator、Window、Location、History 等)
  • 全局函数(alert、confirm、prompt 等)
  • 元素对象类型及其派生类型(包含所有 HTML 元素以及浏览器支持的其他命名空间的元素、元素的父类、实现元素功能的辅助类,还有文档中那些不属于元素的其他内容,除此之外还有文档片段对象 DocumentFragment。)
  • 其他 Web API(XMLHttpRequest、Fetch、WebAudio、WebWorker 等)
  • 全局变量(document、navigator 、location、history、localStorage 等)
  • 全局对象(window:ECMAScript 并没有规定全局对象要怎么访问以及全局对象的额外功能,所以浏览器中的 window 既是全局对象也是代表浏览器窗口的对象,但这样其实有一些问题,不过在这里就不多说了。)
  • 控制台对象(console:ECMAScript 并没有规定一定要使用控制台,所以控制台其实属于脚本引擎自己决定的内容。只不过程序总是要有输入输出还有调试的地方,所以控制台也就差不多成了约定俗成的东西。)