從 ECMAScript 5 開始
July 18, 2022ECMAScript 13(ECMAScript 2022)都已經正式釋出了,現在還從 ECMAScript 5 開始?如果你不想從 ECMAScript 5 開始,那可以參考我寫的《JavaScript 技術手冊》,它不會特意從 ECMAScript 5 開始,而是以你應該怎麼學習一門新語言作為開始,例如,你應該優先使用 let
來建立變數,因此書中會先談 let
而不是 var
。
至於從 ECMAScript 5 開始,這是學習 JavaScript 的不同方向,特別對看過鹹魚時期 JavaScript 到現在的開發者而言,從 ECMAScript 5 開始,並不只是老派風格,也不是懷舊,即便你沒看過鹹魚時期的 JavaScript,從不同的角度學習一門語言,其實也有其價值,特別是你工作上遇上一些萬古文物般的程式碼時。
就語言的部份,還是使用 Node.js 來作為示範平臺吧!就寫這篇文件的時間點上,我使用的是 16.16.0 LTS 的 Windows 版本。
C:\workspace>node -v
v16.16.0
從誕生到 ECMA-262
既然都要從 ECMAScript 5 開始了,那就來談跡四JavaScript 的發展過程吧!
想要令網頁設計者能動態地操作瀏覽器中的網頁、圖片等元件,而且程式碼可以直接撰寫在 HTML 標記之中,Netscape Communications 公司最初是希望 JavaScript 創建者 Brendan Eich,能將 Scheme 語言嵌入到 Navigator 中,然而在這之前,Netscape 與 Sun Microsystems 已經在合作,希望能在 Navigator 中支援 Java,以在 Web 技術及平臺上與微軟競爭。
Netscape 最後決定採用一種可以與 Java 互補,語法也類似的腳本語言(scripting language),為了有個原型來捍衛這個提案,Brendan Eich 在《Effective JavaScript》前言中這麼描述:
1995 年 5 月在管理階層協迫性且互相衝突的命令:「讓它看起來像 Java」、「讓初學者容易上手」、「讓它能控制 Netscape 瀏覽器中幾乎所有的東西」之下,我在十天內建立了 JavaScript。
實際上,JavaScript 一開始命名為 Mocha,1995 年 9 月 Navigator 2.0 的 Beta 版改名為 LiveScript,然而為了行銷這門語言,1995 年 12 月,Netscape Navigator 2.0 Beta 3 中被改名為 JavaScript,以搭上「Java」這個熱門話題 ,並且號稱它是為非程式設計師打造、簡單易用的腳本語言。
實際上 JavaScript 與 Java 之間,除了基礎流程語法及一些關鍵字相似之外,在風格或是典範根本上是兩種完全不同的語言;另一方面,由於設計上倉促急迫,JavaScript 有不少矛盾與古怪的特性,有些矛盾特性今日依舊存在,應該避免使用,然而有些古怪特性,在 20 多年來開發者的經驗與創意持續累積下,卻也成了 JavaScript 中的亮點,成了 JavaScript 開發者都應當掌握及善用的特色。
有些古怪特性並不是亮點,然而有時也無法避免使用,只能去瞭解如何與這類特性共處,這也是學習 JavaScript 必要的一環。
不過當時的行銷策略是成功的,Netscape 當時最大競爭者 Microsoft,1996 年 8 月在其 Internet Explorer 3.0 瀏覽器中,推出了與 JavaScript 語法上極為類似的腳本語言,因為不想與 Sun 處理商標問題,這門語言被命名為 JScript,早期若談到為 Internet Explorer 撰寫 JavaScript 程式碼,其實是在用 JScript 撰寫程式。
然而,因為 JavaScript 與 JScript 極為類似,當時不少開發者混淆了兩者,誤以為 JavaScript 在瀏覽器間的相容性很差,執行效能也不佳,因此覺得 JavaScript 不利於開發,這些都是 JavaScript 不被看好的一些緣由。
知道嗎?JavaScript 是個商標,原屬於 Sun,2010 年 Oracle 併購了 Sun,JavaScript 商標也就屬於 Oracle 擁有了。
同時間有兩門極為相近的語言,Netscape Navigator 與 Internet Explorer 又正值瀏覽器大戰方酣之時,不少人也常混淆JavaScript、JScript,為了讓 JavaScript 成為國際標準,Netscape 於 1996 年 11 月正式向 ECMA(European Computer Manufacturers Association International)提交語言規範以進行標準化,語言規範 ECMA-262 於 1997 年 6 月正式釋出首個版本,亦被稱為 ECMAScript。
在 ECMA-262 出爐以後,JavaScript 在定位上,成為實現 ECMAScript 的語言,只不過開發者多半還是使用 JavaScript 這個名稱。實際上,JScript 或後來的 TypeScript 等語言,也實現了 ECMAScript 規範,然而也包含了規範外的其他語法特性。
真正最早普及,也是 JavaScript 開發者最為熟悉的 ECMAScript 版本是 1999 年 12 月發佈的 ECMA-262 第三版,簡稱 ES3,當中包含了規則表示式(Regular expression)、例外處理等重大特性,JavaScript 開發者會最熟悉這個版本的原因在於,直到下一個規範版本發佈,中間耗費了十年之久的時間。
從 ES3 到 ES5
耗費如此之久的原因之一,是由於 Microsoft 在瀏覽器大戰中獲勝,因為缺少競爭對手,也就沒興趣更新 ECMAScript 規範了,這情況直到 2005 年左右,瀏覽器有了廣大的普及率、Web 應用程式類型多元化、Ajax 技術開始盛行,開發者認知到瀏覽器中 JavaScript 的重要性,加上新一波瀏覽器大戰正在醞釀當中,ECMAScript 規範制定才重新有了進度。
然而,規範制定雖然重新有了進度,卻也陷入了多方政治角力的問題。例如 ActionScript 是 Macromedia(後來被 Adobe 併購)為 Flash 打造的語言(也實現了 ECMAScript 規範),Macromedia 積極地想在標準中包含更多對 ActionScript 的支援,然而遭到 Yahoo、Microsoft 等多方人馬大力反對;另外,下個規範原本預計新增的特性中,包含了 ECMAScript 原本沒有的區塊、類別、模組、產生器等諸多語法,Brendan Eich 與一些規範制定成員,認為這些特性不應該倉促地加入規範,必須慎重評估以免破壞語言原本的特性。
在多方政治角力之後,原本應該是下個版本的 ES4 被否決了,然而,部份針對 ES3 缺失進行改進的特性,原預計被發佈為 ES3.1,後來在 2009 年 12 月重新命名為 ES5。
ES5 釐清了 ES3 中許多模糊不清的規範,重大特性之一是增加嚴格模式(Strict mode),啟用嚴格模式以後,若誤用了過去經驗上,被認為不好的 ECMAScript 特性,將會以直譯或執行錯誤終止程式,其他特性如設值(Setter)、取值(Getter)函式的支援、支援更多的物件屬性設置,JSON 的支援也是 ES5 的重要規範之一。
ES5 的不少特性,對撰寫程式庫的開發者極為重要,某些程度來說,這些特性也是後續 ES6 的基礎(畢竟原本都是源於被否決的ES4),是個重大規範版本,ES5 也被現代瀏覽器廣為實作,認識與善用 ES5,自然就是(當時)ECMAScript 開發者的重要課題之一。
從 ES5 到 ES6
ES5 最初是定位為ES3.1,因而 ES5 語法基本上相容於 ES3,而被否決的ES4中有關於區塊、類別、模組、產生器等諸多語法,被放入了 ES6 的討論,持續調整細節中,在這個過程中,Google Chrome 瀏覽器興起,正式展開新一波瀏覽器大戰,不過這次主流瀏覽器積極擁抱標準,對討論中的 ES6 特性,也開始或多或少地以實驗性質特性支援。
與 Google Chrome 同樣採用 V8 JavaScript 引擎的 Node.js 發佈,將 JavaScript 應用帶出了瀏覽器的世界,成為使用 JavaScript 開發後端(Backend)的寵兒,由於定位在後端開發,相對來說比較沒有瀏覽器版本的部署問題,Node.js 對 ES6 討論中的特性積極地支援,對於 ES6 的討論度以及後來的接受度上,有非常大的幫助。
ES6 規範於 2015 年 6 月正式釋出,並希望之後以年份來區分版本,因此又稱 ECMAScript 2015,不過不少開發者仍習慣使用 ES6 或 ECMAScript 6 來稱呼這個版本,由於 Node.js 與主流瀏覽器的積極支援,ES6 的普及率迅速地上升,成為 ECMAScript 歷史上的重大版本。
認識 TC39 提案
現今要認識 JavaScript,必須知道現階段它是怎麼管理與發展,從 ES6 之後,ECMAScript 採頻繁、每年 6 月釋出新版本的方式,令新版本的發佈常態化,新版本內容僅包含當年已完成的新特性。
主流瀏覽器與 Node.js 都會緊跟著新發佈的規範,針對新特性完成實作,如果想要認識這些特性以善加利用,查詢最新版本的 ECMA-262 雖然是個方式 ,然而規範內容實在過於冗長,最快的方式,其實是是查閱 TC39 的〈ECMAScript proposals〉 。
ECMA 有許多技術委員會(Technical Committees)與任務群組(Task Groups),其中 TC39 就是負責 ECMAScript 規範的技術委員會,語言的提案處理程序在〈The TC39 Process〉中可以看到有五個階段:
- 0:稻草人(Strawperson)
- 1:提案(Proposal)
- 2:草案(Draft)
- 3:侯選(Candidate)
- 4:完成(Finished)
只有 TC39 成員可以建立階段 0 稻草人,此時純綷就是構想,未正式在 TC39 中進行討論,實務上開發者比較感興趣的,應該是能進入階段 3 的提案,這時提案幾乎確定會是未來正式規範的一部份,只待規範上的一些文件完成、審校與核可,各大主流瀏覽器與 Node.js,在這個階段通常也會提供實作了。
提案可能會在階段 3 停留許久,只有在提案來到階段4時,才會成為下個版本 ES 正式規範的一部份,如果想確認特性真正是出現在哪個版本,可以查閱〈Finished Proposals〉中的預計發佈年份(Expected Publication Year),例如,該欄位若標示為 2016,表示發佈於 ECMAScript 2016,也就是 ES7,在本文撰寫的時間點,最新的討論規範版本為 ECMAScript 2023,也就是 ES14。
這系列不會是 JavaScript/ECMAScript 語言入門,我只會寫些語言中我覺得有興趣的特性,這系列也不會是 Node.js 的介紹,方才一連串的簡介,只是為了後續介紹語言核心時的必要準備。