官术网_书友最值得收藏!

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()將腳本文件作為一個模塊來裝載,并有效地識別、提示這兩類錯誤信息。例如在具體的宿主環境中,可以使用其他方法來檢查、區分這兩類錯誤,并且也并不總是需要使用require()來將腳本文件作為模塊裝載。這里采用Node.js來實現示例主要用于展示兩類錯誤的差異。

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

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

主站蜘蛛池模板: 广丰县| 得荣县| 峡江县| 梅河口市| 会同县| 延边| 额敏县| 淮安市| 平湖市| 平南县| 若羌县| 宽甸| 泾川县| 水富县| 剑川县| 石林| 当涂县| 阳泉市| 元江| 永靖县| 理塘县| 夏邑县| 博野县| 深州市| 江川县| 满洲里市| 科技| 双牌县| 嘉善县| 永宁县| 宝丰县| 莱西市| 高邑县| 县级市| 辽宁省| 微山县| 江口县| 侯马市| 福清市| 濮阳市| 马山县|