--- title: 'JS 核心 4 - 文法' tags: JS 核心, Javascript, 運算子、型別與文法 description: 2021/02/03 --- JS 核心 -- 文法 === ## 陳述式與表達式 * **陳述式 ( Statement ):** 用於命令執行指定的一系列操作,<span class="red">不會回傳結果。 無法賦值在其他變數上。</span> * 一開始就會被寫進記憶體中。 ![](https://i.imgur.com/5mLLVmK.png) * **表達式 ( Expression ):** 又可稱為表示式、運算式,經常透過一些符號結合上下語句並運算及<span class="red">回傳結果。</span> * 運算式 (即表達式) : 是任何一段可以取得一個值的程式碼。 * 一開始不會被寫進記憶體,而是在執行時建立這個函數物件,之後可以使用指向該函數記憶體的變數進行呼叫。 ### 函式陳述式 (具名函式) * 直接宣告一個函式,並給他一個名稱 ``` function callName () { ... } ``` ### 函式表達式 (匿名函式表達式) * 先宣告一個變數 * 使用 = (運算子),把後面的函式賦予值到前面的變數上 ``` var callName = function () { ... } ``` :::info :bulb: **注意** 函式陳述式 與 函式表達式 兩者的 Hosting 結果會不一樣。 <span class="red">函式表達式最大的特徵在於他不會受到提升的影響,</span>因此若在函式表達式之前呼叫,它就會出現錯誤訊息。 **[參閱 Hoisting 章節](https://hackmd.io/@peggyted0129/ByrSzuIgO)** ::: ### 陳述式語句 #### 範例 : block 區塊 - 裡面使用 var 宣告變數 ``` { var ming = '小明'; // var 的作用域在函式內 } ``` 以上屬於函式陳述式,若用變數來接收他,會出現錯誤。 ``` var a = { var ming = '小明'; // 跳錯 } ``` #### 範例 : block 區塊 - 裡面使用 const 宣告變數 ``` { const ming = '小明'; // const 變數的作用域只在他所屬的block語句內有用 } console.log(ming); // ming is not defined ``` ### 表達式語句 #### 範例 : 物件實字 - 是JS定義物件的其中一個方法。 ``` { ming = '小明'; } ``` 以上屬於函式表達式,可用變數來接收他。 ``` var a = { ming = '小明'; } ``` ## ASI 自動插入分號 ![](https://i.imgur.com/7jzuNQU.png) ### 範例 : 為什麼下面這段程式碼會無法如預期的 console.log 叫我小明呢? ``` function callName() { return '叫我小明'; } console.log(callName()); // undefined ``` 這是因為這段語法受到ASI的影響,自動被補上分號,而相當於下面這段程式碼 : 這樣的結果就無法正確回傳內容。 ``` function callName() { return; ‘叫我小明’; } console.log(callName()); // undefined ``` ### 範例 : if 少了大括號,後面直接接上else,再直接接上console.log,中間無使用「斷句 ;」隔開 ``` if ( 1 > 10) a = 1 else a = 2 console.log(a) // 2 ``` console.log 可以正確呈現結果 (實際運行結果有自動補上分號) ``` if ( 1 > 10) a = 1; else a = 2; console.log(a); // 2 ``` 如果該行被接在前一行的後面會出現語法錯誤時,就會自動幫前一行加上分號。 ``` if ( 1 > 10) a = 1 else a = 2 console.log(a) ``` ### 範例 : ASI 無正確啟用,就無法把兩者之間隔開 ``` // 跳錯 (intermediate value)(...) is not a function (function(){ console.log('小明'); } () ) (function(){ console.log('小明'); } () ) ``` 若要正常執行需在兩者之間補上分號 ``` (function(){ console.log('小明'); } () ); // 小明 (function(){ console.log('小明'); } () ) // 小明 ``` ### ”不會” 發生 ASI 的規則 1. 新的一行是 `(`、`[`、`/` 開始 (容易出錯的地方) ``` var a = 1 var b = a (a + b).toString() (function() { })() (function() { })() /test/.test(b) ``` 2. 新的一行以 `+`、`-`、`*`、`%` 作開始 (會影響執行結果) ``` var b = a +a ``` 3. 新的一行以 `,`、`.` 作開始 (需注意執行結果) ``` var a = 2 var b = a .toString() ,b = 2 // b 一樣會 var 被宣告 ``` 4. 因此,遇到以上的標點符號前方加入分號也是解決辦法 ``` // 執行錯誤 (function() { })() (function() { })() // 正確 ;(function() { })() ;(function() { })() ``` ## :memo: 學習回顧 :::info * **陳述式:** 用於命令執行指定的一系列操作,<span class="red">不會回傳結果。無法賦值在其他變數上。</span> (一開始就會被寫進記憶體中) * **表達式:** 又可稱為表示式、運算式,<span class="red">會回傳結果</span>。(一開始不會被寫進記憶體中) * 函式表達式最大的特徵在於他不會受到提升的影響,</span>因此若在函式表達式之前呼叫,它就會出現錯誤訊息。 * 函式表達式,可用變數來接收他。反之,函式陳述式若用變數接收會跳錯。 ::: ## :+1: 相關參考文件 :::info [JS 原力覺醒 - 陳述式、表達式](https://ithelp.ithome.com.tw/articles/10218937) ::: <style> .red { color: red; } .green { color: green; } </style>