JavaScript 技术概览
===============

HTML 定义网页的结构与内容，CSS 定义其格式与样式，而 JavaScript 则为网页增加可交互性，创作功能丰富的 Web 应用。

但是，如果从浏览器的范畴去理解“JavaScript”这个术语，它包含了截然不同的两个方面。一方面是 JavaScript 的核心语言（ECMAScript），另一方面是大量的 Web API (en-US)，包括 DOM（文档对象模型）。

JavaScript 核心语言（ECMAScript）
---------------------------

JavaScript 的核心语言是 ECMAScript，是一门由 ECMA TC39 委员会标准化的编程语言。“ECMAScript”是语言标准的术语，但“ECMAScript”和“JavaScript”是可以互换使用的。

该核心语言同样可以被用在非浏览器环境之中，例如 Node.js。

### 哪些内容被纳入 ECMAScript 范畴之中？

除却一些其他元素，ECMAScript 定义了：

* 语法（解析规则、关键词、流程控制、对象初始化，等等）
* 错误处理机制（`throw`、`try...catch`，以及创建用户自定义错误类型的能力）
* 类型（布尔值、数字、字符串、函数、对象，等等）
* 基于原型的继承机制
* 内置对象和函数（`JSON`、`Math`、Array 方法、`parseInt`、`decodeURI`，等等）
* 严格模式
* 模块系统
* 基本内存模型
### 标准化流程

ECMAScript 版本由每年的 ECMA 大会批准并作为标准发布。所有的进展都在 Ecma TC39 GitHub 组织上公开，该组织托管提案、官方规范文本和会议记录。

在 ECMAScript 第 6 版（称为 ES6）之前，规范是几年发布一次，通常用它们的主要版本号来指代（ES3、ES5 等）。在 ES6 之后，规范以发布年份命名（ES2017、ES2018 等）。ES6 是 ES2015 的代名词。*ESNext* 是一个动态名称，指的是撰写本文时的下一个版本。ESNext 中的特性更准确地称为提案，因为根据定义，规范尚未最终确定。

目前委员会批准的 ECMA-262 的快照有 PDF 版本和 HTML 版本。ECMA-262 和 ECMA-402 正处于维护状态，仍在由规范编辑者更新；TC39 网站托管了最新版本的 ECMA-262 和 ECMA-402。

新的语言特性，包括新的语法和 API 的引入以及现有行为的修订，都以提案的形式进行讨论。每个提案都需要经过 4 个阶段的过程，通常在第 3 或 第 4 阶段时，JavaScript 引擎会实现这些提案，以供公众使用。

有关 ECMAScript 历史的更多信息，请参阅维基百科上的 ECMAScript 条目。

国际化 API
-------

由 ECMA TC39 进行标准化的 ECMAScript 国际化 API 规范是在 ECMAScript 语言规范之上额外增加的。国际化 API 为 JavaScript 提供了国际化的规则排序（字符串比较）、数字格式化、日期时间格式化等功能，能够让应用选择语言，并根据实际需要选用功能。本标准在 2012 年 12 月审批通过，可以在 `Intl` 对象页面查看各个浏览器对其的实现情况。如今，国际化规范也每年批准一次，浏览器不断改进其实现。

### 相关资源

你可以通过多种方式参与或跟踪 ECMAScript 语言规范和 ECMAScript 国际化 API 规范和相关资源的目前的工作：

* ECMAScript 语言规范仓库
* ECMAScript 国际化 API 规范仓库
* ECMAScript 提案仓库
* ECMAScript 一致性测试套件仓库
* TC39 会议记录
* ECMAScript 规范讨论；当前邮件列表
* ECMAScript 规范讨论；历史邮件列表档案（至 2021 年 3 月）
DOM API
-------

### WebIDL

WebIDL 规范定义了 ECMAScript 和 DOM 技术之间的交互规范。

### DOM 的核心

文档对象模型（DOM）是用来表达 HTML、XHTML 及 XML 文档中的对象或与其进行交互的**约定**，它是跨平台的，并且与**编程语言无关**。通过调用**DOM 树**上对象的方法可以操纵这些对象。文档对象模型核心是由 W3C (en-US) 进行标准化的，它将 HTML 和 XML 文档抽象成对象，并在其上定义接口以及操纵这些对象的机制，DOM 定义的元素有：

* DOM 核心中定义了文档结构、树模型，以及 DOM 事件架构，包括：`Node`、`Element`、`DocumentFragment`、`Document`、`DOMImplementation`、`Event`、`EventTarget`，等等
* DOM 事件中包括对于 DOM 事件架构的一个不太严格的定义，以及一些特殊事件。
* DOM 元素遍历以及 DOM 范围对象等其他内容。

从 ECMAScript 的角度来看，DOM 规范中定义的对象被称作“宿主对象”。

### HTML DOM

HTML，Web 的标记语言，是根据 DOM 定义的。位于 DOM 核心抽象概念之上，HTML 还定义了元素的意义。比如元素的 `className` 属性以及例如 `document.body` 这样的 API。

HTML 规范同时还约束了元素之间的关系，例如无序列表 `<ul>` 元素中，只能以 `<li>` 元素作为子元素来表达列表项。还有就是禁止使用标准中未定义的元素和属性。

想了解更多关于 `Document` 对象、`Window` 对象以及其他 DOM 元素的信息？请访问 MDN 的 DOM 文档。

其他值得关注的 API
-----------

* `setTimeout` 和 `setInterval` 函数最早被定义在 HTML 标准的 `Window` 接口下。
* XMLHttpRequest 使得发起异步 HTTP 请求成为可能。
* Fetch API 为网络请求提供了更符合人体工程学的抽象。
* CSS 对象模型 将 CSS 规则抽象成对象。
* WebWorker 允许进行并行计算。
* WebSocket 允许进行底层双向通信。
* Canvas 2D Context 是 `<canvas>` 元素的绘图 API。
* WebAssembly 接口 提供了 JavaScript 代码和 WebAssembly 模块之间的通信工具。

非浏览器环境（如 Node.js）通常不提供 DOM API——因为它们不与文档进行交互，但它们仍然会实现很多 web API，例如 `fetch()` 和 `setTimeout()`。

有哪些 JavaScript 的实现？
-------------------

mozilla.org 上托管了两个 JavaScript 实现。**首个** JavaScript 由网景公司的 Brendan Eich 创建，并不断地更新以符合 ECMA-262 Edition 5 及其之后的标准版本。这个引擎，代号 SpiderMonkey ，是由 C/C++ 语言开发的。而 Rhino 引擎，主要由 Norris Boyd（同样也是在网景公司）创建，则是一个 Java 语言开发的 JavaScript 实现。与 SpiderMonkey 类似，Rhino 符合 ECMA-262 Edition 5 标准。

有很多优化技术如 TraceMonkey (Firefox 3.5)、JägerMonkey (Firefox 4) 和 IonMonkey 被不断添加到了 SpiderMonkey JavaScript 引擎。并且提升 JavaScript 执行效率的工作一直在进行。

除了以上实现，还有其他一些流行的 JavaScript 引擎，如：

* Google 的 V8，在 Google Chrome 浏览器和较新的 Opera 浏览器中使用。这同时也是Node.js使用的引擎。
* JavaScriptCore (SquirrelFish/Nitro)，被用在了一些 WebKit 浏览器如 Apple Safari。
* Carakan，用在旧版本 Opera 中。
* Chakra 引擎，用在 Internet Explorer 中（尽管它实现的语言被正式地称作为“JScript”来避免商标问题）。

每个 mozilla.org 的 JavaScript 引擎都提供了 公用 API 使程序开发者能将其 JavaScript 嵌入自己的软件中。目前最常见的 JavaScript 宿主环境是网页浏览器。浏览器一般通过 API 创建“宿主对象”来负责将DOM 反射到 JavaScript 中。

另一个常见的 JavaScript 应用是作为服务端脚本语言。JavaScript 服务器提供宿主对象代表 HTTP 请求和响应，随后可以通过 JavaScript 程序来动态的生成 Web 页面。Node.js便是一个流行的例子。

Shell
-----

JavaScript shell 允许你快速测试代码片段或 JavaScript 代码，而无需重载 web 页面。其在开发和代码调试中非常有用。

### 独立的 JavaScript shell

以下 JavaScript shell 是与 Perl 或 Python 类似的独立的环境：

* Node.js——Node.js 是用于构建快速、可扩展的网络应用的平台。
* ShellJS——用于 Node.js 的便携式 Unix shell 命令。
### 基于浏览器的 JavaScript shell

以下 JavaScript shell 是通过浏览器的 JavaScript 引擎运行代码的：

* Firefox 有一个内置的 JavaScript 控制台，支持多行编辑。
* Babel 交互式解释器——一个基于浏览器的、用于试验下一代 JavaScript 特性的交互式解释器。
* TypeScript playground——一个基于浏览器的在线运行环境，用于试验新的 JavaScript 特性（通过 tsc 编译器）和 TypeScript 语法。
工具和资源
-----

用于编写和调试 JavaScript 代码的实用工具。

Firefox 开发者工具

包括 Web Console、JavaScript Profiler、Debugger 等。

JavaScript Shell

Javascript Shell 使你可以即时测试 JavaScript 代码片段。

TogetherJS

添加 TogetherJS 到你的网站，让用户实时互助，协作更简单。

Stack Overflow

你可以在 StackOverflow 查看或者发布带有 JavaScript 标签的问题。

JSFiddle

编辑 JavaScript、CSS 和 HTML 并获得实时结果。使用外置资源，并同你的团队在线合作。

Plunker

Plunker 是一个在线社区，用于创建、协作和共享你的 Web 开发创意。编辑你的 JavaScript、CSS 和 HTML 文件并获取实时结果和文件结构。

JSBin

JS Bin 是一个开源的协作式的 web 开发调试工具。

Codepen

Codepen 也是一个 Web 协作工具，可用作展示实时结果的 playground。

StackBlitz

StackBlitz 同样是一个支持调试的在线 playground，它支持部署使用了 React、Angular 等技术的全栈应用

RunJS

RunJS 是一个桌面端便笺式 playground，可提供实时执行结果并支持调用 Node 与浏览器 API。