---
# System prepended metadata

title: JavaScript 基礎課程 (6)
tags: [JavaScript]

---

---
robots: noindex, nofollow
tags: JavaScript
---

# JavaScript 基礎課程 (6)

## 上次上課提要
- Object（物件）
- Array（陣列）

## 今日進度
- Loop（迴圈）：
  - While loop
  - For loop
- 迴圈與陣列的搭配使用
  - `for`
  - `for of`
  - `Array.forEach`
- 跳脫迴圈
- 略過某次迭代

## 更新 ESLint 設定
替換 `javascript-basics/.eslintrc.json` 檔案裡的內容：
```json=
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "airbnb-base"
  ],
  "parserOptions": {
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "rules": {
    "func-names": "off",
    "no-alert": "off",
    "no-console": "off",
    "no-continue": "off",
    "no-plusplus": [
      "error",
      { "allowForLoopAfterthoughts": true }
    ],
    "no-restricted-syntax": [
      "error",
      {
        "selector": "ForInStatement",
        "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array."
      },
      {
        "selector": "LabeledStatement",
        "message": "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand."
      },
      {
        "selector": "WithStatement",
        "message": "`with` is disallowed in strict mode because it makes code impossible to predict and optimize."
      }
    ],
    "prefer-arrow-callback": "off",
    "prefer-const": "off",
    "prefer-template": "off"
  }
}
```

## Loop（迴圈）
- 迴圈的本質是**重複做同一件事**
- 在某種情況下重複做同一件事（while 迴圈）
- 重複做同一件事固定次數（for 迴圈）

### While Loop
- 當特定**條件**發生時，重複做某件事
- 跟 `if` 長得很像，可以把它想成「會重複執行的 if 條件」

```javascript=
while (trueOrFalse) {
  // Do something...
}
```

> 當我吃土的時候，錢省著點花。
> While I'm poor, I would spend less money.

```javascript=
while (iAmPoor) {
  spendLessMoney();
}
```

```javascript=
// 動物園入場管制
let MAX_PEOPLE_COUNT = 500;
let peopleCount = 0;

function letVisitorPass() {
  peopleCount = peopleCount + 1; // 按下計數器
}

while (peopleCount < MAX_PEOPLE_COUNT) {
  letVisitorPass();
}
```

### For Loop
- 重複做某些事特定的**次數**
- 跟 while 迴圈不同，for 迴圈要設定「計數器」
- 常搭配陣列一起使用，此時重點概念是：「每一、逐一」

```javascript=
function stepForward() {
  console.log('角色往前走了一步！');
}

// 讓遊戲角色往前走五步
for (let step = 0; step < 5; step++) {
  stepForward();
}

// '角色往前走了一步！'
// '角色往前走了一步！'
// '角色往前走了一步！'
// '角色往前走了一步！'
// '角色往前走了一步！'
```

`for` 迴圈小括號裡面有三組指令：
1. `let step = 0`：初始化
2. `step < 5`：評估條件
3. `step++`：每次迭代結束後會執行的指令

#### 程式練習（5 ~ 10 分鐘）
嘗試用 for 迴圈在 console 秀出 `2 * 1` ~ `2 * 9` 的乘法表：
```
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
```

### 跳脫迴圈
`break;` 會立即終止並跳脫目前的迴圈。

```javascript=
// 窮人模式
let isLotteryWinner = false;

while (isPoor) {
  spendLessMoney();
  buyLotteryTicket();
}
```

```javascript=
// 富人模式
let isLotteryWinner = false;

while (isPoor) {
  if (isLotteryWinner) {
    break; // 中斷並跳脫迴圈
  }

  spendLessMoney();
  buyLotteryTicket();
}
```

### 略過某次迭代（iteration）
`continue;` 可以略過目前這次迭代，但不會跳脫迴圈。

```javascript=
for (let i = 0; i < 7; i++) {
  if (i === 4) {
    // 「4 不吉利，不要寫出來！」
    continue; // 略過這次迭代
  }

  console.log(i);
}

// 0
// 1
// 2
// 3
// 5
// 6
```

## 迴圈與陣列的搭配使用
- 通常用陣列儲存資料之後，我們會希望在某個時機，針對每一個陣列裡的值逐一做同樣一件事
- 在陣列裡造訪每個值的行為叫做「遍歷」（traversal）

### `for`
```javascript=
// 課堂點名
//   index:       0      1      2       3      4      5
let students = ['詠晴', '品妍', '宥蓁', '柏睿', '宥廷', '柏宇'];

for (let i = 0; i < students.length; i++) {
  console.log(students[i]);
}
// '詠晴'  students[0]
// '品妍'  students[1]
// '宥蓁'  students[2]
// '柏睿'  students[3]
// '宥廷'  students[4]
// '柏宇'  students[5]
```

### `for ... of`
```javascript=
let students = ['詠晴', '品妍', '宥蓁', '柏睿', '宥廷', '柏宇'];
for (let student of students) {
  console.log(student);
}

// '詠晴'
// '品妍'
// '宥蓁'
// '柏睿'
// '宥廷'
// '柏宇'
```

優點：語法較 `for` 迴圈簡單；可讀性高
缺點：只能存取每次迭代的「值」，無法存取「索引值」

### `Array.forEach`
用 Array 內建的 method，可以幫我們遍歷陣列裡的值。

```javascript=
myArray.forEach(...);
```

```javascript=
let students = ['詠晴', '品妍', '宥蓁', '柏睿', '宥廷', '柏宇'];

// '第 1 位，詠晴'
// '第 2 位，品妍'

// 特定情況下 function 可以不給名字，
// 例如把 function 當作參數傳給別的 function 的時候
students.forEach(function (student, index) {
  console.log('第 ' + (index + 1) + ' 位，' + student);
});
```

優點：不容易寫錯；裡面的 function 可以再獨立拆出去，程式碼較好維護
缺點：需要對 `function` 語法有基本的了解

#### 字串模板（Template literals）
除了用 `+` 串連字串之外，其實還有一個更新、更好用的語法：
```javascript=
let myName = 'Arthur';

'Hi, I am ' + myName + '.'
`Hi, I am ${myName}.`
```

### 程式練習
1. 用迴圈新增 10 個隨機小數到一個陣列（while 迴圈或 for 迴圈皆可）
2. 建立第二個陣列，裡面只保留第一個陣列裡數值 > 0.5 的值（使用 `for ... of` 或 `Array.forEach` 皆可）
> 提示：呼叫 `Math.random` 可產生隨機小數

```javascript=
// 動態產生
let firstArray = [
  // ... 十個介於 0 ~ 1 之間的小數
];

// 動態產生
let secondArray = [
  // ... 只保留 firstArray 大於 0.5 的小數
];
```

## w10 作業
:::danger
期限：**5/2（週日）23:59**
:::

### 透過 Slack 發問
- 可問：
  - 上課的內容
  - 跟 JavaScript 有關的問題
  - 看不懂的 ESLint 錯誤訊息
  - 寫作業或課堂練習時遇到的困難
- 程式類的問題請附上程式碼或錯誤訊息
  - 行數少的話，直接用 Slack 的 code block 功能附上
  - 行數多的話請貼到 CodePen 再附上連結


---


<div style="display: flex; justify-content: space-between;">
  <a href="https://hackmd.io/@gsscsid/javascript-basics-5">⬅️&nbsp;JavaScript 基礎入門課程 (5)</a>
  <a href="https://hackmd.io/@gsscsid/javascript-basics-7">JavaScript 基礎入門課程 (7)&nbsp;➡️</a>
</div>
