ECMAScript 是什麼? ECMAScript 是 Ecma International 在 ECMA-262 標準裡定義的程式語言規格,JavaScript 是依照這份規格實作出來的語言。常聽到的「ES6」「ES2015」「ES2022」都是這份規格的版本名稱:規格每年出一版,新語法與新方法就是這樣一年一年加進 JavaScript。本文說明 ECMAScript 與 JavaScript、DOM 各自負責什麼,ES6 和年度版本怎麼對應,並用 Node.js 與 Chrome 跑出不同年度加入的語法,最後整理新語法進入規格的 TC39 提案流程。
ECMAScript 是什麼:JavaScript 的標準規格
ECMAScript 規格的 Introduction 寫明,ECMAScript 以數項起源技術為基礎,最知名的是 Netscape 的 JavaScript 與 Microsoft 的 JScript。這個語言由 Netscape 的 Brendan Eich 發明,最早出現在 Navigator 2.0 瀏覽器,規格第一版於 1997 年 6 月由 Ecma 大會通過。
MDN 對兩者關係的說法是:JavaScript 由 Ecma International 標準化,標準化後的版本稱為 ECMAScript,文件是 ECMA-262,所有支援這個標準的應用程式行為都一致。所以日常可以這樣分:
| 名稱 | 是什麼 | 誰負責 |
|---|---|---|
| ECMAScript | 語言規格:語法、型別、Array、Promise 等內建物件 | Ecma International 的 TC39 委員會,文件是 ECMA-262 |
| JavaScript | 依規格實作的語言,平常說的「寫 JavaScript」 | 各家引擎與執行環境 |
| DOM | 操作網頁文件的介面,例如 document | W3C、WHATWG |
MDN 明確寫到,ECMAScript 規格並不描述 DOM。同時它也提醒,規格是給實作引擎(例如 Firefox 的 SpiderMonkey、Chrome 的 V8)的人看的,不是寫給一般寫程式的人,寫程式請看 JavaScript 文件。
規格只管語言,物件由宿主環境提供
ECMA-262 的 Overview 說,規格定義的 ECMAScript 並不打算自給自足:規格裡沒有輸入外部資料或輸出運算結果的機制。這些東西由宿主環境(host environment)補上,規格舉的例子是網頁瀏覽器,會提供視窗、對話框、cookie 等物件。
把同一段程式分別丟給 Node.js 與瀏覽器就看得出來。globalThis 與 setTimeout 兩邊都有,window、document 只有瀏覽器有,process、require 只有 Node.js 有:
console.log('typeof globalThis =', typeof globalThis);
console.log('typeof window =', typeof window);
console.log('typeof document =', typeof document);
console.log('typeof process =', typeof process);
console.log('typeof require =', typeof require);
console.log('typeof setTimeout =', typeof setTimeout);

圖中上半是 Node.js v22.20.0,下半是 Chrome 158.0.8127.18(headless)的輸出,兩邊都是同一種 JavaScript 語法,差別在宿主環境提供的物件。document 這類瀏覽器物件的操作可另外學;這裡只要記得,在 Node.js 執行 document.title 會得到 ReferenceError: document is not defined,原因是宿主環境沒有這個物件,不是語法錯誤。
ES6、ES2015、第 6 版:版本名稱怎麼對應
ECMA-262 的版本有兩種叫法,「第幾版」與「ES+年份」,指的是同一份規格:
- 第 6 版的標題是 ECMAScript 2015 Language Specification,2015 年 6 月通過。ES6 就是這一版,也寫成 ES2015。
- 規格 Introduction 寫明,ECMAScript 2016 是第一個採用 TC39 新的「每年發行」節奏與開放開發流程的版本。所以第 6 版之後,每年 6 月左右出一版:第 7 版是 2016,第 8 版是 2017,依此類推。
- 第 6 版以前是用編號:第 1 版 1997 年 6 月、第 2 版 1998 年 8 月、第 3 版 1999 年 12 月、第 5 版 2009 年 12 月、第 5.1 版 2011 年 6 月。第 4 版沒有發行,Ecma 頁面特別註明「ECMA-262 Edition 4」這個編號保留了但從未使用。
Ecma 官方頁面目前列出的最新版是 ECMAScript 2026,第 17 版,2026 年 6 月。tc39.es/ecma262 上的則是持續更新的草稿:規格寫明它包含最近一次年度快照,加上已達 Stage 4 的提案,這些會進入下一次的年度快照。本文撰寫時這份草稿的標題是 ECMAScript 2027。
第 6 版是變動最大的一版
第 6 版的 Introduction 寫得很清楚:這是持續了十五年的努力成果,主要新增包含模組、class 宣告、區塊作用域、迭代器與產生器、Promise、解構等。規格同時寫明,第 6 版為之後固定、漸進式的語言與函式庫增強奠定了基礎,也就是後面年度版本的起點。
年度版本各加了什麼
規格 Introduction 對前幾個年度版本的描述如下:ES2016 新增指數運算子(**)與 Array.prototype.includes;ES2017 新增 async function,以及 Object.values、Object.entries。再往後,常見語法與方法所屬的版本如下(版本以 Ecma 規格頁面核對,年份以 TC39 finished-proposals 為準):
| 語法或方法 | 規格版本 | 範例 |
|---|---|---|
指數運算子、Array.prototype.includes | ES2016(第 7 版) | 2 ** 10、[1, 2].includes(2) |
| async function | ES2017(第 8 版) | async function f() {} |
可選串連 ?.、空值合併 ?? | ES2020(第 11 版) | user.profile?.name ?? '訪客' |
Array.prototype.at | ES2022(第 13 版) | [10, 20, 30].at(-1) |
Object.groupBy | ES2024(第 15 版) | Object.groupBy(items, fn) |
核對方式是對照各版本的規格頁面:第 13 版(2022)有 Array.prototype.at 的條目,第 12 版(2021)沒有;第 15 版(2024)有 Object.groupBy,第 14 版(2023)沒有;第 11 版(2020)的文法有 OptionalExpression 與 CoalesceExpression,第 10 版(2019)沒有。
跑一次各年度語法
下面這段程式依序用到上表的語法:
console.log('ES2016 2 ** 10 =', 2 ** 10);
console.log('ES2016 includes(2) =', [1, 2, 3].includes(2));
async function hello() {
return 'async ok';
}
hello().then((v) => console.log('ES2017 async function =', v));
const user = { profile: null };
console.log('ES2020 user.profile?.name =', user.profile?.name);
console.log('ES2020 ?? 預設值 =', user.profile?.name ?? '訪客');
console.log('ES2022 [10, 20, 30].at(-1) =', [10, 20, 30].at(-1));
console.log(
'ES2024 Object.groupBy =',
JSON.stringify(Object.groupBy([1, 2, 3, 4], (n) => (n % 2 ? 'odd' : 'even')))
);

圖中兩個環境的輸出一致:2 ** 10 是 1024,user.profile?.name 遇到 null 時不報錯而回傳 undefined,?? 補上預設值「訪客」,at(-1) 取到最後一個元素 30,Object.groupBy 把陣列依奇偶分成 odd、even 兩組。async function 的結果因為是 Promise,排在同步輸出之後才印出。
這也說明了「新語法能不能用」要看執行環境的版本:同樣的語法,在版本較舊的環境可能不被支援。Node.js 官方文件說,Node.js 以現代版 V8 建置,跟進 V8 讓 ECMA-262 的新功能能在 Node.js 使用;V8 認為穩定的功能預設開啟、不需要任何旗標。要看各個 Node.js 版本支援哪些 ECMAScript 功能,官方文件指向 node.green;查目前 Node.js 內建的 V8 版本可執行 node -p process.versions.v8。
數字與日期的格式化(例如千分位)不在 ECMA-262,而是另一份 ECMA-402 國際化 API 規格;ECMA-262 的參考規範明列它,Intl.NumberFormat 就在 ECMA-402。用法可前往〈JS 數字加逗號 / 轉換千分位顯示(toLocaleString 與正規表達式)〉觀看。
新語法怎麼進規格:TC39 提案流程
誰決定哪些語法能進 ECMAScript?是 Ecma 的 TC39 委員會,流程記載在 tc39.es/process-document。官方說明共有六個階段:一個 strawperson 階段加五個成熟度階段,每個階段的推進都要委員會核准。
| Stage | 官方說明的狀態 |
|---|---|
| 0 | 新提案,委員會目前沒有在考慮 |
| 1 | 委員會正在考慮,找出問題範圍與可能的解法 |
| 2 | 委員會選定偏好的解法,但設計還是草稿,可能大幅改動 |
| 2.7 | 原則上通過,進入驗證階段,之後主要依測試、實作與使用回饋調整 |
| 3 | 建議開始實作,預期不會有變動,但仍可能因網頁相容性或實作回饋做必要調整 |
| 4 | 功能完整,準備納入標準,不再變動 |
進入 Stage 4 的條件包含:兩個相容的實作通過 Test262 驗收測試、已有實際出貨實作的使用經驗,以及已對規格倉庫送出整合規格文字的 pull request。Stage 4 的提案會整理在 tc39/proposals 的 finished-proposals 清單,並寫明預期發布的年份;前面表格的年份就是查這份清單。
規格的年度節奏,TC39 流程文件寫的是:預計每年 7 月把規格送交 Ecma 大會批准;3 月的會議把 Stage 4 提案納入並從主線切出新版本,之後只接受編輯性修改。所以一個語法什麼時候「能用」要分兩件事看:進入 Stage 4 代表已有實作可用,而它屬於哪個年度版本,看 finished-proposals 的預期年份與當年度規格。
寫程式時哪裡會碰到 ECMAScript 版本
最常碰到的地方是工具設定。例如 ESLint 的 languageOptions.ecmaVersion,官方文件說預設是 "latest",表示被檢查的程式碼所用的 ECMAScript 版本,同時決定可用的語法與全域變數;可以設成 3 或 5,或 2015 到現在之間的任一年份,官方建議多數情況用預設的 "latest"。ESLint 的基本設定可前往〈ESLint 是什麼?JavaScript 程式碼檢查工具的用途、規則與設定檔入門〉。
另一種是看到「不是標準」的語法。JSX 就是例子:規格寫明 JSX 是 ECMAScript 的類 XML 語法擴充,沒有定義語意,也不打算讓瀏覽器或引擎直接實作,要由工具轉成標準 ECMAScript,細節可前往〈JSX 是什麼?React JSX 語法規則、與 HTML 的差異和轉譯原理〉。碰到 <h1> 這種寫在 JavaScript 裡的標記時,可以用本文的分法判斷:它不在 ECMAScript 裡。
整理成幾個判斷原則:
- 語法或內建物件(
Array、Promise、?.)屬於 ECMAScript,行為看引擎版本。 window、document屬於瀏覽器宿主環境與 DOM 規格,process、require屬於 Node.js,都不在 ECMAScript 裡。- 看到「ES6」「ES2015」是同一個版本,是 2015 年 6 月通過的第 6 版;年份版本從 ES2016 開始每年一版。
- 想知道新語法能不能用:先到 finished-proposals 查它屬於哪個年度,再查執行環境(例如 Node.js 查 node.green)支援與否。
參考資料與延伸閱讀
- Ecma International:ECMA-262
- ECMAScript® 2027 Language Specification(最新草稿,tc39.es)
- ECMAScript 2015 Language Specification(第 6 版)
- ECMAScript® 2022 Language Specification(第 13 版)
- ECMAScript® 2024 Language Specification(第 15 版)
- ECMAScript® 2023 Internationalization API Specification(ECMA-402)
- TC39:The TC39 Process
- tc39/proposals:Finished Proposals
- MDN:JavaScript Guide – Introduction
- Node.js:ECMAScript 2015 (ES6) and beyond
- ESLint:Language Options
- 站內延伸閱讀:〈ESLint 是什麼?JavaScript 程式碼檢查工具的用途、規則與設定檔入門〉、〈JSX 是什麼?React JSX 語法規則、與 HTML 的差異和轉譯原理〉、〈JS 數字加逗號 / 轉換千分位顯示(toLocaleString 與正規表達式)〉
發佈留言