---
# System prepended metadata

title: Javascript程式語言

---

# Javascript程式語言

> 2020-08-16 上課筆記

## 基本資料型態
### 常數 ![](https://i.imgur.com/HR1VBJe.png)
```
const i = 1.02e2  // 1.02 * 10^2
```

### 基本資料型態與分類(兩者差異在於「變數值存入變數的方式」)
| 分類 | 資料型別 | 說明 |
| -------- | -------- | -------- |
| 基本型     | number     | 數值     |
| 基本型     | string     | 字串     |
| 基本型     | boolean     | 布林     |
| 基本型     | symbol     | 符號     |
| 基本型     | null/undefined     | 空/未定義     |
| 參考型     | array     | 陣列(資料集合-可透過索引值存取標籤)     |
| 參考型     | object     | 物件(資料集合-可透過名稱存取標籤)     |
| 參考型     | function     | 函式(函數)-一連串處理(步驟)的集合     |

## 基本型
基本型態的變數可直接填入變數值
## 參考型
參考型態的變數則用以儲存參考值(用以儲存「值」的記憶體位置)。

### 陣列
```
n = [1, 2, 3]
n = ['a', 'b', 'c']
n = [1, 'a', 2, 'b']
console.log(n)
console.log(n[2])
```

### 物件
```
n = {a: 1, b: 2, c: 3, 123:5}
console.log('物件', n['b'])
console.log('物件', n['123'])
```

### 小數
```
f = 0.7
f *= 10
console.log((1*10 - f)/10)
```
> 注意：
> - Javascript是用二進制來計算數值，之後再轉換成十進制，因此會有誤差。
> - 引用Math或BigDecimal.js等等可以解決浮點數運算的問題。


### 變數定義
#### let與var的不同 ![](https://i.imgur.com/HR1VBJe.png)
- let無法重複定義，但var可以。
- let指令能更詳細的控制變數的有效範圍。

### 樣板字串-嵌入變數 ![](https://i.imgur.com/HR1VBJe.png)
格式：**${變數名稱}**
```
var age = 7
var des = `我今年${age}歲`
```

### 多行字串 ![](https://i.imgur.com/HR1VBJe.png)
```
let test = 
`今天天氣熱
明天天氣好`

console.log(test)
```

## 運算子
### 指派運算子
```
a = 5
console.log(a += 5) // a = a + 5
console.log(a -= 2) // a = a - 2 (a=10 -> a=8)
console.log(a *= 3) // a = a * 3 (a=8 -> a=24)
console.log(a /= 4) // a = a / 4 (a=24 -> a=6)
console.log(a %= 5) //a = a % 5 (a=6 -> a=1)
```

### 基本型態與參考型態經過指派後的差別
1. 基本型態會複製本值，因此指派後的修改不影響原來變數內容。
2. 參考型態為複製參考，因此指派後的修改會影響原來變數內容。
```
a = 'str';
console.log('基本型指派前:', a);
a1 = a;
a1 = 'rts';
console.log('基本型指派後:', a);

b = [1, 2, 'v'];
console.log('參考型指派後:', b);
b1 = b;
b1[2] = 99;
console.log('參考型指派後:', b);
```
結果:
```
基本型指派前: str
基本型指派後: str
參考型指派後: [ 1, 2, 'v' ]
參考型指派後: [ 1, 2, 99 ]
```
### 解構指派 ![](https://i.imgur.com/HR1VBJe.png)
#### 陣列解構指派
例如將一個陣列元素分別指定給不同的變數，原本用法:
```
c = [1, 2, 3, 4, 5];
c1=c[0]
c2=c[1]
c3=c[2]
c4=c[3]
c5=c[4]
```
解構指派用法:
```
c = [1, 2, 3, 4, 5];
[c1, c2, c3, c4, c5] = c;
```
> 注意：要用中括號包住
更多範例:
```
d = [1, 2, 3, 4, 5];
let [d1, d2, d3, d4, d5] = d;
console.log(d1, d2, d3, d4, d5);
```
#### 透過「...」將放不下的元素以陣列方式指定
```
e = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let [e1, e2, e3, e4, e5, ...other] = e;
console.log(e1, e2, e3, e4, e5, other);
```

#### 變數交換
```
c = 5;
d = 9;
// [temp = c
// c = d
// d = temp
[c, d] = [d, c];
console.log(c, d);
```
#### 物件解構指派
```
let aa, bb, cc;
let o1, o2, o3;

array1 = [1, 2, 3];
obj1 = {a:1, b:2, c:3};

[aa, bb, cc] = array1;
console.log(aa, bb, cc);
({o1, o2, o3} = obj1);   //物件指派寫法
console.log(o1, o2, o3);
```
> 變數名稱必須與屬性名稱相同

#### 巢狀物件解構指派
```
c = {
    x: 1,
    y: 2,
    z: 3,
    child: {
        x1: 4,
        y1: 5, 
        z1: 6
    }
};
let {x, y, z, child: {x1, y1, z1}} = c;
console.log(x, y, z, x1, y1, z1)
```
#### 設定別名
```
// 設定別名
c = {
    a: 1,
    b: 2,
    c: 3
}

let {a:name, b:title, c:content} = c;
console.log('name=', name, 'title=', title, 'content=', content);

array1 = [1, 2, 3];
obj1 = {a:1, b:2, c:3};

let aa, bb, cc;
let o1, o2, o3;

[aa, bb, cc] = array1;
console.log(aa, bb, cc);
({a:o1, b:o2, c:o3} = obj1); //物件指派寫法
console.log(o1, o2, o3);
```

### 比較運算子
```
console.log(1 == '1');
console.log(1 === '1');
console.log(1 != '1');
console.log(1 !== '1');

a = 3;
b = 5;

if(a > b) {
    console.log('a比b大');
}
else {
    console.log('a比b小');
}

console.log('a比b' + (a > b ? '大':'小'));
```

### 捷徑運算
下列值皆為false:
- 空字串('')
- 數值0、Nan(Not a Number)
- null、undefine
> 執行順序:由左到右做比較
```
b = 0;
c = 3;

a = b && c;
console.log(a);

a = b || c;
console.log(a);
```
結果:
```
0
3
```

```
a1 = 'a';
a2 = 99;
a3 = false;
a4 = [0, 0]
a5 = {}

console.log(a1 && a2 || a3 && a4 && a5)
console.log(a2 && a5 || a4 && a5)
console.log(a5 || a2 && a3 && a4 && a5)
console.log(a4 || a2 || a3 || a5)
```
輸出結果:
```
99
{}
{}
[ 0, 0 ]
```

##### 練習
1. a, b為兩個字串，如果相同就顯示「相同」否則顯示「不同」。

### delete運算子
```
a = 4;
delete a;
console.log('a=', a); // 這裡會出現例外錯誤，因為a變數被刪除了

// 明確宣告的變數無法刪除（let或var）
var a9 = 9;
delete a9;
console.log('a9=', a9); // a9仍然存在

// 陣列索引刪除後，後面的會往前移，只是原來的元素存取時會出現undefined
a = [1, 2, 3];
delete a[1];
console.log(a[1]);
console.log(typeof a);

// 刪除屬性，物件本身不會被刪除
a = {a:1, b:2};
delete a.b;
console.log(a);
```

### typeof運算子
```
a = 9;
console.log(typeof a);
a = '9';
console.log(typeof a);
a = false;
console.log(typeof a);
a = [1,2,3];
console.log(typeof a);
a = 1.5;
console.log(typeof a);
```
輸出結果:
```
number
string
boolean
number
object
```
> 陣列跟物件都只回傳object

### 運算子優先順序
```
a = 7
console.log((3 + 5) * 6);
console.log(a);

z = a += 9;
console.log(z);
z += 9 + 8 * 2;
console.log(z);
```
> 如果無法確定運算子優先權，但想優先運算的話，可以使用小括號包圍，因為小括號優先權最高。

## 控制語法
程式結構一般分為三類：
1. 依照撰寫順序執行的「循序」。
2. 依照條件分岐的處理「選擇」。
3. 重複執行特定處理的「重複」。

### if


### switch


### for

### for...in

### for...of ![](https://i.imgur.com/HR1VBJe.png)


### bread/continue

### 一次跳出巢狀迴圈 - label

### 例外處理 - try...catch...finally


### 避免JavaScript錯誤與法 - Strict模式

### 非同步載入外部程式 - async/defer屬性
##### 將<script>標籤放在網頁最後面（例如: </body>前面）

```
'use strict';
```


| 分類 | 限制 |
| -------- | -------- |
| 變數     | 禁止省略var     |
| 變數     | 禁止使用未來保留的關鍵字     |
| 變數     | 禁止參數、屬性名稱重複     |
| 變數     | 禁止undefined/null指派     |
| 指令     | 禁止使用with     |
| 指令     | 禁止存取arguments.callee     |
| 指令     | Eval指令宣告之變數     |
| 其他     | 函數內的this無法轉成全域物件(會變成undefined)     |
| 其他     | 禁止「0-」的８進位常數值     |


##### 優點：
1. 避免JavaScript陷阱。
2. 執行速度比Strict快。
3. 可增加未來相容性。
4. 可更加了解JavaScript的禁止狀況。


##### 使用HTML5非同步與法
```
<script async src="app.js"></script>
```
> 以src屬性設定的程式會透過非同步方式載入，在載入結束之後才接著執行。

```
<script async defer src="app.js"></script>
```
> 整個頁面都下載及分析完成後才會執行程式。



## 函式
##### 何謂函式：
1. 一段事先準備好的特定功能程式碼區塊。
##### 函式功用：
1. 減少重複的程式碼。
2. 讓程式更簡潔更有架構。
3. 讓程式碼更容易閱讀。
##### 函式結構：
1. 含式名稱。
2. 程式碼區塊。
3. 參數。
4. 回傳值。

命名規則：
1. 第一個字元只能是英文大小寫、底線、$號
2. 第2個字元及之後可以是英文大小寫、數字、底線、$號。
3. Javascriot保留字不可作為函式名稱。
4. 命名方式為snake命名法，全小寫，以底線分隔單字。

