---
# System prepended metadata

title: JS 核心 4 - 文法
tags: [' 運算子、型別與文法', JS 核心, ' Javascript']

---

---
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>