本章涵蓋#

  • JavaScript 語言的核心特性
  • JavaScript 引擎的核心組成
  • JavaScript 開發的三大最佳實踐

1.1 理解 JavaScript 語言#

許多 JavaScript 開發者因為 JavaScript 採用類似 C 的語法(與 C#、Java 相似),而誤以為自己已經充分理解這門語言。但這其實是個陷阱——JavaScript 本質上更偏向函式導向(functionally oriented),有些概念與其他主流語言有根本性的差異。

JavaScript 與其他語言的關鍵差異:

  • Functions are first-class objects:函式可以像其他物件一樣被創建、賦值給變數、作為參數傳遞、甚至作為回傳值
  • Function closures:閉包是指函式會主動維持(“closes over”)其函式體中所使用的外部變數,這個概念雖然常被誤解,但對 JavaScript 至關重要
  • Scopes:直到最近,JavaScript 才有 block-level 變數;過去只有 global 與 function-level 變數
  • Prototype-based object orientation:不同於 C#、Java、Ruby 等使用 class-based 物件導向的語言,JavaScript 使用 prototype 來實現物件導向

JavaScript 由 objectsprototypesfunctionsclosures 之間緊密的關係所構成。理解這些概念之間的強連結,能為任何類型的應用程式開發奠定堅實基礎。

此外,本書也聚焦於以下進階特性:

  • Generators:可按需產生多個值並在請求間暫停執行的函式
  • Promises:提供對非同步程式碼更好的控制
  • Proxies:允許控制對特定物件的存取
  • Advanced array methods:使陣列操作更優雅
  • Maps:用於建立字典集合;Sets 用於處理唯一值集合
  • Regular expressions:簡化原本複雜的程式碼
  • Modules:將程式碼拆分為較小的、相對獨立的片段

1.1.1 JavaScript 將如何演進?#

ECMAScript 委員會已完成 ES7/ES2016 標準。相較於 ES6,ES7 是相對小幅的升級,因為委員會的目標是轉向更小規模的年度增量更新。

本書深入探討 ES6,並涵蓋 ES7 特性如 async 函式(用於處理非同步程式碼,在 Chapter 6 討論)。

語言規格的年度更新並不代表開發者能立即使用新特性——JavaScript 程式碼需要由 JavaScript 引擎執行,因此必須等待引擎支援。

1.1.2 Transpilers 讓你今天就能使用明天的 JavaScript#

由於瀏覽器的快速釋出週期,通常不用等太久就能獲得新特性支援。但若需要在舊瀏覽器上使用新語法,可以使用 transpilers(“transformation + compiling”)——將前沿的 JavaScript 程式碼轉換為等效的、可在大多數當前瀏覽器中運行的程式碼。

常見的 transpiler 包括:

  • Traceur(Google 開發)
  • Babel

1.2 理解瀏覽器#

JavaScript 應用程式可在多種環境中執行,但一切的起源——也是本書特別關注的環境——是瀏覽器(browser)。瀏覽器提供多種概念與 API 供開發者使用:

  • Document Object Model (DOM):用戶端 web 應用程式 UI 的結構化表示,由 HTML 建構而成。開發者需要深入理解 DOM 的建構方式(Chapter 2)以及如何撰寫高效的 DOM 操作程式碼(Chapter 12)
  • Events:絕大多數 JavaScript 應用程式是**事件驅動(event-driven)**的,程式碼在回應特定事件時執行。事件包含網路事件、計時器、使用者操作(點擊、滑鼠移動、鍵盤按鍵等)。Timers 尤其重要,可用於處理長時間運算與流暢動畫(Chapter 13)
  • Browser API:瀏覽器提供的 API,允許存取裝置資訊、本地儲存資料、與遠端伺服器通訊等

Figure 1.1: 用戶端 Web 應用程式依賴瀏覽器提供的基礎設施

各瀏覽器之間仍存在差異、bug 與不一致行為。制定全面的跨瀏覽器策略,其重要性幾乎等同於精通 JavaScript 本身。本書在 Chapter 14 深入探討跨瀏覽器開發策略。

1.3 使用當前最佳實踐#

精通 JavaScript 語言與跨瀏覽器議題還不夠,還需要掌握以下最佳實踐(best practices)

1.3.1 Debugging(除錯)#

過去除錯 JavaScript 意味著使用 alert 來驗證變數值。如今,每個主流瀏覽器都提供了開發者工具:

  • Firebug:Firefox 的開發者擴充套件,帶動了整個除錯工具的發展
  • Chrome DevTools:Chrome 與 Opera 使用
  • Firefox Developer Tools:Firefox 內建
  • F12 Developer Tools:Internet Explorer 與 Microsoft Edge 內建
  • WebKit Inspector:Safari 使用

這些工具提供相似的功能:探索 DOM、除錯 JavaScript、編輯 CSS、追蹤網路事件等。Chrome Dev Tools 也可用來除錯 Node.js 應用程式。

1.3.2 Testing(測試)#

本書使用 assert 函式作為主要的測試工具,用來斷言某個前提條件為 true 或 false:

assert(condition, message);

例如:

assert(a === 1, "Disaster! a is not 1!");

assert 函式並非 JavaScript 語言的標準功能,本書在附錄 B 中自行實作。

1.3.3 Performance analysis(效能分析)#

使用 console.timeconsole.timeEnd 來測量程式碼執行時間:

console.time("My operation");

for (var n = 0; n < maxCount; n++) {
  /*perform the operation to be measured*/
}

console.timeEnd("My operation");

由於單次操作執行太快難以測量,通常需要重複執行多次(數千甚至數百萬次)以獲得可靠的測量值。

1.4 提升技能可轉移性#

深入理解 JavaScript 基礎原理與核心 API 的知識,能讓你成為更全面的開發者。透過瀏覽器與 Node.js(源自瀏覽器的環境),你可以開發幾乎任何類型的應用程式:

  • 桌面應用程式:使用 NW.js 或 Electron,以標準 HTML、CSS 和 JavaScript 建構跨平台桌面 UI
  • 行動應用程式:使用 Apache Cordova 等框架,以 wrapped browser 搭配平台特定 API 開發行動 app
  • 伺服器端應用程式與嵌入式裝置應用:使用 Node.js,其執行 JavaScript 程式碼並依賴事件機制,與瀏覽器共享許多底層原理

1.5 Summary#

  • 用戶端 web 應用程式是當今最受歡迎的應用類型,原本只用於其開發的概念、工具和技術已滲透到其他應用領域
  • 要深入理解 JavaScript,需掌握其核心機制:functions、closures 與 prototypes,以及 generators、promises、proxies、maps、sets 和 modules 等新特性
  • JavaScript 開發需要理解瀏覽器:DOM、events、timers 與 browser API
  • 三大最佳實踐不可或缺:debugging、testing、performance analysis