- JavaScript語言精髓與編程實踐(第3版)
- 周愛民
- 1585字
- 2020-07-02 15:37:33
2.1 語法綜述
語言中的標識符一般可以分為兩類,一類用于命名語法、符號等抽象概念,另一類用于命名數據(的存儲位置)。前者被稱為“語法關鍵字”,后者則被稱為“變量”和“常量”。并且由此引入了一個概念:綁定。從標識符的角度來說,綁定分為語法關鍵字與語義邏輯的綁定,以及變量與它所存儲數據和位置性質的綁定。
其中,語法關鍵字對語義邏輯的綁定結果,是對作用域的限定;變量對位置性質的綁定結果,則是對變量生存周期的限定。
2.1.1 標識符所綁定的語義
我們由此得以明確程序語言中“聲明”的意義:所謂聲明,即約定數據的生存周期和邏輯的作用域。由于這里的“聲明”已經涵蓋了邏輯與數據(這相當于“程序”的全部),因此整個編程的過程,其實被解釋成了“說明邏輯和數據”的過程:
■ 純粹陳述“數據”的過程,被稱為變量和類型聲明。
■ 純粹陳述“邏輯”的過程,被稱為語句(含流程控制子句)。
■ 陳述“數據與(算法的)邏輯”的關系的過程,被稱為表達式。
表2-1闡述了JavaScript中的主要標識符與其語義之間的關系。
表2-1 標識符與其語義關系的基本分類

注1:“符號(Symbol)”是ES6添加的新數據類型,可以同其他數據一樣綁定給變量或標識符。
注2:表達式首先是與數據相關的,但因為存在運算的先后順序,所以也有邏輯相關的含義。
注3:JavaScript中的邏輯語句是有值的,因此它也是數據相關的。這一點與其他多數語言不一樣。
注4:一些模塊的實現方案與邏輯(例如流程控制)相關,例如Node.js。但一些實現方案則是邏輯無關的,例如ECMAScript的靜態模塊機制就是如此,它只描述模塊之間的依賴關系。
除了“聲明”在語義上對綁定內容的限制之外,當一個被聲明的標識符(變量、常量或符號等)去綁定一個數據時,事實上還有其他兩個方面的語義:數據(受作用域限制)的生存周期及可寫性。這三者是JavaScript在:
■ 用于顯式數據聲明的語句let/var/const、函數聲明與類聲明,以及
■ 數種for語句、try...catch語句、賦值語句,以及
■ 在函數調用和new運算符等語法中通過形式參數傳入值。
這些語義中都存在著隱式或顯式數據聲明的原因:它們有著各自在“作用域、值和可寫性”三方面的不同性質。
從ES6開始提供了一些新的具有綁定標識符語義的語法,包括賦值模板(assignment pattern)、剩余參數(rest parameters)、默認參數/參數默認值(default parameters/default values)以及展開運算符(spread operator)等。盡管在這幾類綁定操作上存在著處理細節上的不同,但總體還是圍繞上述三種性質來設計的,如表2-2所示。
表2-2 綁定操作的語義說明

注1:在實參中傳入undefined值,表明對應的形參使用參數默認值。
注2:使用const/let/var時可以理解為“標識符聲明+一般賦值運算”兩個步驟。但在一般賦值運算過程中,其左側操作數盡管可以使用賦值模板和剩余參數的語法,但是不具有標識符聲明的語義(變量的隱式聲明除外)。
表2-2意味著其實只有“展開運算”是作為運算符來使用的,其他所有特性都是聲明語法中的綁定,它們在詞法階段就決定了標識符的那些性質,例如它與(將來的)值之間的關系。
2.1.2 識別語法錯誤與運行錯誤
一般來說,JavaScript引擎會在代碼裝入時先進行語法分析,如果語法分析通不過,整個腳本代碼塊都不執行;當語法分析通過時,腳本代碼才會執行。若在執行過程中出錯,那么在同一代碼上下文中、出錯點之后的代碼將不再執行。
不同引擎處理這兩類錯誤的提示的策略并不相同,例如,在JScript腳本引擎環境中,兩種錯誤的提示大多數時候看起來是一樣的。在ES6之前,由于沒有專門的裝載模塊的操作,“載入一個腳本文件然后嘗試語法分析(并執行)”這個操作通常要有兩組代碼來負責,前者可能依賴宿主的文件加載(例如,瀏覽器中的XmlHttpRequest或Node.js中內置的fs模塊),而后者則通常依賴腳本引擎的eval()來動態執行。在這種情況下,很難給出有關這兩類錯誤的標準提示信息。
在Node.js中可以方便地使用require()將腳本文件作為一個模塊來裝載,并有效地識別、提示這兩類錯誤信息。例如:

事實上,Node.js命令行上傳入的主文件也是作為模塊加載的,因此下面的示例與上述效果相同:

或者,也可以直接使用Node.js在命令行上做語法檢測:

- Learning Microsoft Windows Server 2012 Dynamic Access Control
- 計算思維與算法入門
- 玩轉Scratch少兒趣味編程
- Spring Boot開發與測試實戰
- Visual C++串口通信開發入門與編程實踐
- 羅克韋爾ControlLogix系統應用技術
- Getting Started with SQL Server 2012 Cube Development
- Learning Apache Mahout Classification
- SpringBoot從零開始學(視頻教學版)
- JQuery風暴:完美用戶體驗
- Learning Grunt
- Unity Android Game Development by Example Beginner's Guide
- 視窗軟件設計和開發自動化:可視化D++語言
- Mobile Forensics:Advanced Investigative Strategies
- 產品架構評估原理與方法