美思 技術雜談:JavaScript - 程式設計史上最美麗的錯誤

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

JavaScript 可以說是程式語言史上最美麗的錯誤,在短短十天內匆忙開發的新語言,竟然可以跨越前端 (front end)、後端 (back end)、桌面端 (desktop)、行動端 (mobile) 等不同應用情境,成為新一代的當紅炸子雞。應該很少會有程式語言的函式庫和框架有 JavaScript 的那麼豐富。在 2017 的 StackOverflow 的調查中,JavaScript 榮登最常用的程式語言,在各大語言排名中,JavaScript 都位居前幾名。

曾經有數個技術,試圖取代 JavaScript,以下是一些實例:

  • VBScript (retired)
  • Java Applet (retired)
  • ActiveX (legacy and dangerous)
  • Flash (almost retired)
  • Silverlight (retired)
  • CoffeeScript (fading out)
  • Dart (well designed but not popular)

這些技術的出現,不僅僅是技術上的理由,往往有政治上的考量;如果,所有的網頁設計師都用某一家的技術,那麼,這個市場將會相當地龐大。由於網頁自由開放的特性,前述的事情實際上不會發生;經過自由軟體運動後,程式設計者對於有獨占性質的技術會更加審慎評估。Dart 就是一個最好的實例,Dart 本身設計上算是完善,相關工具也是相當完整,但是,Dart 意圖取代 JavaScript 這件事情犯了政治上的錯誤,使得 Dart 無法進一步成為主流。目前各大瀏覽器背後的勢力都樂於接受 JavaScript 做為網頁共通的語言,即使是 Web Assembly 也不會完全取代 JavaScript,而會以 JavaScript 模組的角色和目前的網路技術互補。

然而,JavaScript 的坑,也是相當地多。就像是「JavaScript 優良部分」和其他討論 JavaScript 的書籍中,如何避免這些坑坑洞洞,就成為每個 JavaScript 程式設計者的天堂路。然而,依靠人的力量去克服這些東西,有許多缺點:第一個,每個程式設計者都要重覆學習,浪費大量人力資源;第二,人類不像機器,每次動作都可以一模一樣不出錯,即使是老練的程式設計者偶而也會犯錯。對於資訊人來說,如果能用工具自動完成的事情,為什麼要耗費自己寶貴的時間呢?於是,JavaScript trans-compiler 出現了,像是 CoffeeScript、Dart、Babel (ES6)、TypeScript 等。

一開始,就像一部分讀者,筆者對於 trans-complier 這種技術很不能接受。但是,其實人類早就在用這種技術了。早期的人需要手動撰寫組合語言,但自從 C 發明後,現在還在寫組合語言的人就少了。大部分的高階語言,像是 Python 或 Ruby 或 R,也都是用 C 寫的;這些語言都保留 C API,必要時可以和 C 程式碼橋接。當然,JavaScript transpiler 和 C 編譯器略有不同,我們不是將這些語言的程式碼轉為機械碼,而是轉為 JavaScript。這一部分是現實上的考量,因為目前瀏覽器中只能執行 JavaScript;另外一個原因則是轉為 JavaScript 後程式碼可在不同情境中重覆利用。

早期試圖突破 JavaScript 困境的方案是 CoffeeScript,這個語言採用類似 Ruby 的語法,說實在的,CoffeeScript 的程式碼還蠻賞心悅目的,筆者也曾經跟風學了一陣子。然而,CoffeeScript 其實有一些問題,由於 CoffeeScript 和 JavaScript 語法不相容,程式碼無法直接利用,通常需要轉換後才能使用。而大部分線上的 JavaScript 程式碼範例都是以原生的 JavaScript 來撰寫,如果使用 CoffeeScript 來改寫必需要在自己心裡轉換一次,而 CoffeeScript 最後又把我們想的程式碼轉回 JavaScript。這樣一來一往,最後筆者索性回頭寫原生的 JavaScript。

後來,筆者又接觸到 Babel 和 TypeScript 這兩個工具。這兩個工具較 CoffeeScript 來說,有一個額外的優勢,這兩個工具大抵上其語法相容於原生的 JavaScript,Babel 直接把 ECMAScript 6 拿來用,而 TypeScript 則是採用類似 ECMAScript 7 的內容;由於可以銜接原有的 JavaScript 的知識,學習曲線較小。為了相容於現有的 JavaScript,這兩種語言都會將程式碼轉為原生的 JavaScript,也就是說,可以把這兩個工具新增的語法視為一種語法糖 (syntactic sugar)。

一開始筆者比較看好 Babel,因為 Babel 是直接拿 ECMAScript 6 直接轉為現有的 JavaScript,我們等於是預先學習未來的 JavaScript。但實質上的益處並沒有想像的那麼大。以目前來說,瀏覽器對 ECMAScript 6 的支援仍在緩步進行中,如果目前 (2017) 就要上線的專案,仍然要回頭用 ECMAScript 5 的語法。而動態型別語言的缺點,並沒有消失。

最近,筆者在國外討論區注意到 TypeScript 這個新的語言。簡單地說,TypeScript 在原來的 JavaScript 語法外,額外增加一些類似 Java 或 C# 等靜態型別語言的語法和特性。目前的趨勢看來,TypeScript 受到較多的注目,甚至 Google 的 Angular 2 也優先使用 TypeScript。最近筆者也試著用 TypeScript 寫一些小型專案,大體上印象還不錯;偶爾會碰到一些小問題,需要上網搜尋解決方法。

比較幾個 JavaScript trans-compilers,也可以發現 TypeScript 是最熱門的:

除了 JavaScript transpiler 外,JavaScript 的生態圈也是相當龐雜,像是工作流程自動化就有 Grunt 和 Gulp 等方案,套件管理也有 UMD、AMD、SystemJS、Browserify 等不同方案,更不要提前令人眼花瞭亂的前端框架,如果讀者想知道 JavaScript 的生態圈,可以到 The State of JavaScript 那裡看一看。說實在的,光是要了解這些工具的差異,從中選擇適合自己的工具,就要花上不少的時間。短時間內,JavaScript 的戰國時代應該還不會結果。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。