1. 程式人生 > 其它 >第 1 章 什麼是 JavaScript

第 1 章 什麼是 JavaScript

1995 年,JavaScript 問世。當時,它的主要用途是代替 Perl 等伺服器端語言處理輸入驗證。在此之前,要驗證某個必填欄位是否已填寫,或者某個輸入的值是否有效,需要與伺服器的一次往返通訊。網景公司希望通過在其 Navigator 瀏覽器中加入 JavaScript 來改變這個局面。在那個普遍通過電話撥號上網的年代,由客戶端處理某些基本的驗證是讓人興奮的新功能。緩慢的網速讓頁面每次重新整理都考驗著人們的耐心。

從那時起,JavaScript 逐漸成為市面上所有主流瀏覽器的標配。如今,JavaScript 的應用也不再侷限於資料驗證,而是滲透到瀏覽器視窗及其內容的方方面面 JavaScript 已被公認為主流的程式語言,能夠實現複雜的計算與互動,包括閉包、匿名(lambda)函式,甚至超程式設計等特性。不僅是桌面瀏覽器,手機瀏覽器和螢幕閱讀器也支援 JavaScript,其重要性可見一斑。就連擁有自家客戶端指令碼語言 VBScript 的微軟公司,也在其 Internet Explorer(以下簡稱 IE)瀏覽器最初的版本中包含了自己的 JavaScript 實現。

從簡單的輸入驗證指令碼到強大的程式語言,JavaScript 的崛起沒有任何人預測到。它很簡單,學會用只要幾分鐘;它又很複雜,掌握它要很多年。要真正學好用好 JavaScript,理解其本質、歷史及侷限性是非常重要的。

1.1 簡短的歷史回顧

隨著 Web 日益流行,對客戶端指令碼語言的需求也越來越強烈。當時,大多數使用者使用 28.8kbit/s 的調變解調器上網,但網頁變得越來越大、越來越複雜。為驗證簡單的表單而需要大量與伺服器的往返通訊成為使用者的痛點。想象一下,你填寫完表單,單擊“提交”按鈕,等 30 秒處理,然後看到一條訊息,告訴你有一個必填欄位沒填。網景在當時是引領技術革新的公司,它將開發一個客戶端指令碼語言來處理這種簡單的資料驗證提上了日程。

1995 年,網景公司一位名叫 Brendan Eich 的工程師,開始為即將釋出的 Netscape Navigator 2 開發一個叫 Mocha(後來改名為 LiveScript)的指令碼語言。當時的計劃是在客戶端和伺服器端都使用它,它在伺服器端叫 LiveWire。

為了趕上釋出時間,網景與 Sun 公司結為開發聯盟,共同完成 LiveScript 的開發。就在 Netscape Navigator 2 正式釋出前,網景把 LiveScript 改名為 JavaScript,以便搭上媒體當時熱烈炒作 Java 的順風車。

由於 JavaScript 1.0 很成功,網景又在 Netscape Navigator 3 中釋出了 1.1 版本。尚未成熟的 Web 的受歡迎程度達到了歷史新高,而網景則穩居市場領導者的位置。這時候,微軟決定向 IE 投入更多資源。就在 Netscape Navigator 3 釋出後不久,微軟釋出了 IE3,其中包含自己名為 JScript(叫這個名字是為了避免與網景發生許可糾紛)的 JavaScript 實現。1996 年 8 月,微軟重磅進入 Web 瀏覽器領域,這是網景永遠的痛,但它代表 JavaScript 作為一門語言向前邁進了一大步。

微軟的 JavaScript 實現意味著出現了兩個版本的 JavaScript:Netscape Navigator 中的 JavaScript,以及 IE 中的 JScript。與 C 語言以及很多其他程式語言不同,JavaScript 還沒有規範其語法或特性的標準,兩個版本並存讓這個問題更加突出了。隨著業界擔憂日甚,JavaScript 終於踏上了標準化的征程。

1997 年,JavaScript 1.1 作為提案被提交給歐洲計算機制造商協會(Ecma)。第 39 技術委員會(TC39)承擔了“標準化一門通用、跨平臺、廠商中立的指令碼語言的語法和語義”的任務(參見 TC39-ECMAScript)。TC39 委員會由來自網景、Sun、微軟、Borland、Nombas 和其他對這門指令碼語言有興趣的公司的工程師組成。他們花了數月時間打造出 ECMA-262,也就是 ECMAScript(發音為“ek-ma-script”)這個新的指令碼語言標準。

1998 年,國際標準化組織(ISO)和國際電工委員會(IEC)也將 ECMAScript 採納為標準(ISO/IEC-16262)。自此以後,各家瀏覽器均以 ECMAScript 作為自己 JavaScript 實現的依據,雖然具體實現各有不同。

1.2 JavaScript 實現

雖然 JavaScript 和 ECMAScript 基本上是同義詞,但 JavaScript 遠遠不限於 ECMA-262 所定義的那樣。沒錯,完整的 JavaScript 實現包含以下幾個部分(見下圖):

  • 核心(ECMAScript)
  • 文件物件模型(DOM)
  • 瀏覽器物件模型(BOM)

1.2.1 ECMAScript

ECMAScript,即 ECMA-262 定義的語言,並不侷限於 Web 瀏覽器。事實上,這門語言沒有輸入和輸出之類的方法。ECMA-262 將這門語言作為一個基準來定義,以便在它之上再構建更穩健的指令碼語言。Web 瀏覽器只是 ECMAScript 實現可能存在的一種宿主環境(host environment)。宿主環境提供 ECMAScript 的基準實現和與環境自身互動必需的擴充套件。擴充套件(比如 DOM)使用 ECMAScript 核心型別和語法,提供特定於環境的額外功能。其他宿主環境還有伺服器端 JavaScript 平臺 Node.js 和即將被淘汰的 Adobe Flash。

如果不涉及瀏覽器的話,ECMA-262 到底定義了什麼?在基本的層面,它描述這門語言的如下部分:

  • 語法
  • 型別
  • 語句
  • 關鍵字
  • 保留字
  • 操作符
  • 全域性物件

ECMAScript 只是對實現這個規範描述的所有方面的一門語言的稱呼 。JavaScript 實現了 ECMAScript,而 Adobe ActionScript 同樣也實現了 ECMAScript。

1. ECMAScript 版本

ECMAScript 不同的版本以“edition”表示(也就是描述特定實現的 ECMA-262 的版本)。ECMA-262最近的版本是第 10 版,釋出於 2019 年 6 月。ECMA-262 的第 1 版本質上跟網景的 JavaScript 1.1 相同,只不過刪除了所有瀏覽器特定的程式碼,外加少量細微的修改。ECMA-262 要求支援 Unicode 標準(以支援多語言),而且物件要與平臺無關(Netscape JavaScript 1.1 的物件不是這樣,比如它的 Date 物件就依賴平臺)。這也是 JavaScript 1.1 和 JavaScript 1.2 不符合 ECMA-262 第 1 版要求的原因。

ECMA-262 第 2 版只是做了一些編校工作,主要是為了更新之後嚴格符合ISO/IEC-16262 的要求,並沒有增減或改變任何特性。ECMAScript 實現通常不使用第 2 版來衡量符合性(conformance)。

ECMA-262 第 3 版第一次真正對這個標準進行更新,更新了字串處理、錯誤定義和數值輸出。此外還增加了對正則表示式、新的控制語句、try/catch 異常處理的支援,以及為了更好地讓標準國際化所做的少量修改。對很多人來說,這標誌著 ECMAScript 作為一門真正的程式語言的時代終於到來了。

ECMA-262 第 4 版是對這門語言的一次徹底修訂。作為對 JavaScript 在 Web 上日益成功的迴應,開發者開始修訂 ECMAScript 以滿足全球 Web 開發日益增長的需求。為此,Ecma T39 再次被召集起來,以決定這門語言的未來。結果,他們制定的規範幾乎在第 3 版基礎上完全定義了一門新語言。第 4 版包括強型別變數、新語句和資料結構、真正的類和經典的繼承,以及操作資料的新手段。

與此同時,TC39 委員會的一個子委員會也提出了另外一份提案,叫 “ECMAScript 3.1”,只對這門語言進行了較少的改進。這個子委員會的人認為第 4 版對這門語言來說跳躍太大了。因此,他們提出了一個改動較小的提案,只要在現有 JavaScript 引擎基礎上做一些增改就可以實現。最終,ES3.1 子委員會贏得了 TC39 委員會的支援,ECMA-262 第 4 版在正式釋出之前被放棄。

ECMAScript 3.1 變成了 ECMA-262 的第 5 版,於 2009 年 12 月 3 日正式釋出。第 5 版致力於釐清第 3 版存在的歧義,也增加了新功能。新功能包括原生的解析和序列化 JSON 資料的 JSON 物件、方便繼承和高階屬性定義的方法,以及新的增強 ECMAScript 引擎解釋和執行程式碼能力的嚴格模式。第 5 版在 2011 年 6 月釋出了一個維護性修訂版,這個修訂版只更正了規範中的錯誤,並未增加任何新的語言或庫特性。

ECMA-262 第 6 版,俗稱 ES6、ES2015 或 ES Harmony(和諧版),於 2015 年 6 月釋出。這一版包含了大概這個規範有史以來最重要的一批增強特性。ES6 正式支援了類、模組、迭代器、生成器、箭頭函式、期約、反射、代理和眾多新的資料型別。

ECMA-262 第 7 版,也稱為 ES7 或 ES2016,於 2016 年 6 月釋出。這次修訂只包含少量語法層面的增強,如 Array.prototype.includes 和指數操作符。

ECMA-262 第 8 版,也稱為 ES8、ES2017,完成於 2017 年 6 月。這一版主要增加了非同步函式(async/await)、SharedArrayBuffer 及 Atomics API,以及Object.values()/Object.entries()/Object.getOwnPropertyDescriptors()和字串填充方法,另外明確支援物件字面量最後的逗號。

ECMA-262 第 9 版,也稱為 ES9、ES2018,釋出於 2018 年 6 月。這次修訂包括非同步迭代、剩餘和擴充套件屬性、一組新的正則表示式特性、Promise finally(),以及模板字面量修訂。

ECMA-262 第 10 版,也稱為 ES10、ES2019,釋出於 2019 年 6 月。這次修訂增加了 Array.prototype.flat()/flatMap()、String.prototype.trimStart()/trimEnd()、Object.fromEntries()方
法,以及 Symbol.prototype.description 屬性,明確定義了 Function.prototype.toString() 的返回值並固定了 Array.prototype.sort()的順序。另外,這次修訂解決了與 JSON 字串相容的
問題,並定義了 catch 子句的可選繫結。