The Most Familiar Stranger - JavaScript - 文法
Tags: javascript, beginners, chinese
Published: 2023-05-07 05:31:28

[分享記錄檔 YouTube](https://www.youtube.com/watch?v=CIeTN6hMgq0&list=PLal-nRIQU5sunSCOSeZZEzUrXUXF22gep&index=3)

# 陳述式與表達式

在 JS 的文件或技術文章常常看到 陳述式、表達式 等字眼，但他們是什麼 ? 有什麼差異呢 ? 了解後才能正確理解這些文件、文章在表達的內容，也能幫助我們更靈活運用 JS 的語法。

### 陳述式 Statement

陳述式分為以下幾類：

- 宣告 ( var、function … )
- 流程控制 ( block、if else … )
- 迴圈 ( for、while … )
- 其他 ( import、export … )

* 各類詳細有哪些可參考 MDN - [陳述式與宣告](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements)

陳述式的例子：變數宣告

```jsx
var a;
```

陳述式的例子：block

```jsx
{
	// do something here	
}
```

### 表達式 Expression

表達式的特點就是會**回傳結果**，所以任何有回傳結果的都可以稱為表達式。

常見的有：

- 變數、常數
- 運算子
- 函式呼叫
- 取用物件屬性
- …

* 各類詳細有哪些可參考 MDN - [運算式與運算子](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators)

表達式的例子：常數

```jsx
1   // 1
```

表達式的例子：運算子

```jsx
1 === 1   // true
```

<aside>
💡 兩者的主要**差異**在於：

陳述式：是執行某些操作的句子，但**不會回傳結果**
表達式：**會回傳結果**

</aside>

### 補充

通常在實務上表達式會跟陳述式混用，例如：

```jsx
if (true) {
	doSomethingIfIsTrue();
}
```

true、doSomethingIfIsTrue() 都是表達式，if 則是陳述式


# ASI自動插入分號

ASI ( Automatic Semicolon Insertion )

以下情況不會自動插入分號：

- 新的一行以  ( 、 [ 、 /  開始
- 新的一行以  + 、 - 、 * 、 %  開始
- 新的一行以  , 、 .  開始

如果遇到問題，可以在出問題的那行最開頭加上 ; 


# 運算子

JavaScript 有以下幾種運算子

- 賦值運算子
- 比較運算子
- 算術運算子
- 邏輯運算子
- 條件 (三元) 運算子
- …

* 詳細可參考 MDN - [運算式與運算子](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Expressions_and_Operators)

### 賦值運算子

```jsx
x = 1;

x += 1;   // x = x + 1;
```

```jsx
const props = {
	name: 'John',
	device: 'iPhone',
}

function f() {
	const { name, device } = props;   // 解構賦值
	...
}
```

### 比較運算子

會比較運算元並基於比較的結果回傳邏輯值。運算元可以是數字，字串，邏輯，或物件的值。

```jsx
1 == 1;       // true
'a' != 'a';   // false
```

字串的比較是基於字典序的，使用 Unicode 的值。

```jsx
'A' > 'a';   // false
```

在多數情況下，假如兩個運算元不具有相同型態， JavaScript 會嘗試將它們轉換成相同型態。

轉型會轉為 **數字** 或 **字串** 後進行比較

```jsx
'1' == 1;    // true
false == 0;  // true
```

使用嚴格比較則會比較值跟型別。

```jsx
'1' === 1;   // false
```

### 算術運算子

```jsx
let a = 8;
let b = 2;

a + b;    // 10
a - b;    // 6
a * b;    // 16
a / b;    // 4
a % b;    // 0
a ** b;   // 64
a++;      // 9
b--;      // 1

-a;       // -9
+'3';     // 3
+true;    // 1
```

<aside>
⚠️ ++a 跟 a++ 的行為是有所不同的

</aside>

```jsx
let a = 1;
console.log(++a);   // 2，++a 會先把 a 設定為 2 再傳回 2
console.log(a++);   // 2，a++ 會先把 2 回傳再把 a 設定為 3
console.log(a);     // 3
```

### 邏輯運算子

```jsx
// &&， expression1 && expression2 
// 假如 表達式1 可以被轉成 false 回傳 表達式1，否則回傳 表達式2

true && true;   // true
false && true;  // false
0 && 1;         // 0
'a' && 'b';     // b

// ||， expression1 || expression2
// 假如 表達式1 可以被轉成 true 回傳 表達式1，否則回傳 表達式2

true || false;   // true
false || false;  // false
0 || 1;          // 1
'a' || 'b';      // 'a'

// !， !expression
!true;           // false
!false;          // true
!0               // true
!'a'             // false
```

# 優先性與相依性

### 優先性

JavaScript 的運算子有預設的先後順序，從高到低如下：

| 運算子類型 | 屬於該類別的運算子 |
| --- | --- |
| 成員 | . [] |
| 呼叫/建立 實例 | () new |
| 反向/增加 | ! ~ - + ++ -- typeof void delete |
| 乘法/除法 | * / % |
| 加法/減法 | + - |
| 位元移動 | << >> >>> |
| 關係運算子 | < <= > >= in instanceof |
| 相等性 | == != === !== |
| 位元 and | & |
| 位元 xor | ^ |
| 位元 or | | |
| 邏輯 and | && |
| 邏輯 or | || |
| 條件運算子 | expression ? a : b |
| 指定運算子 | = += -= *= /= %= <<= >>= >>>= &= ^= |= |
| 逗點運算子 | , |

### 相依性

在運行表達式時所需要的其他資源，如：變數、函式、物件等。這就是相依性

```jsx
let x = 10;
let y = 20;

let result = x + y;   // 表達式 x + y 依賴變數 x, y

function square(num) {
	return num * num;
}

let squaredResult = square(result); 
// 表達式 square(result) 依賴函式 square 和變數 result
```