---
# System prepended metadata

title: 基礎網頁前端學習紀錄-  2
tags: [front - end]

---

# 📚 前端網頁開發基礎(javascript) - 學習筆記

> [!Note]
> **播放清單連結：** [點此前往](https://youtube.com/playlist?list=PL-g0fdC5RMbqW54tWQPIVbhyl_Ky6a2VI&si=R7yjmSfWzsqPtw7e)
> **學習總覽：** 雖然已經學過了基礎的HTML、CSS、Javascript用來做一個網站，但是都是依靠AI來完成，希望藉由這個播放清單來複習一下。

---

## 🚀 學習進度

- [x] **影片 11:** JavaScript 簡介、快速開始
- [x] **影片 12:** JavaScript 資料、資料型態
- [x] **影片 13:** JavaScript 變數、常數
- [x] **影片 14:** JavaScript 運算符號
- [x] **影片 15:** JavaScript 流程控制：判斷式
- [x] **影片 16:** JavaScript 流程控制：迴圈基礎
- [x] **影片 17:** JavaScript 流程控制：迴圈指令
- [x] **影片 18:** JavaScript：函式基礎
- [x] **影片 19:** JavaScript 函式回傳值
- [x] **影片 20:** JavaScript 物件基礎

---

## 🎬 影片 11: JavaScript 簡介、快速開始

### 🎯 本集重點 (Key Takeaways)
* **重點一：JavaScript (JS) 是網頁的「大腦與肌肉」**
    * 它是一種程式語言，專門用來為網頁添加**互動性**、**動態效果**與**邏輯功能**。
* **重點二：JS 與 Java 無關**
    * 儘管名稱相似，但它們是兩種完全不同的程式語言，就像「太陽」和「太陽餅」一樣。
* **重點三：使用 `<script>` 標籤**
    * JavaScript 程式碼需要被包在 `<script>` 標籤中，才能被 HTML 文件辨識並執行。
* **重點四：`console.log()` 是開發者的好朋友**
    * 這個指令可以將訊息、變數等內容印在瀏覽器的「開發者主控台」中，是學習與除錯的基礎必備工具。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 什麼是 JavaScript (JS)？**
    * **網頁三位一體**：如果將網頁比喻成一個人，那麼 HTML、CSS 和 JavaScript 各司其職：
        * **HTML (骨架)**：建立網頁的基本結構與內容。
        * **CSS (外觀/衣服)**：負責美化網頁，設定樣式、排版與顏色。
        * **JavaScript (大腦/肌肉)**：賦予網頁互動能力，可以回應使用者的操作、處理資料、改變 HTML 和 CSS 等。
    * 它是製作**動態網頁**的基礎，主要應用在前端網頁開發。

---

* **2. 如何在網頁中執行 JavaScript？**
    * 主要有兩種方式，與我們之前學的 CSS 非常相似：

    * **方法一：內部腳本 (Internal Script)**
        * 直接將程式碼寫在 HTML 檔案的 `<script>` 標籤中。適合小規模或單頁的練習。
        ```html
        <body>
            <script>
                console.log("Hello Javascript");
            </script>
        </body>
        ```
        > [!TIP]
        > **最佳實踐**：習慣上會將 `<script>` 標籤放在 `</body>` 結束標籤的正前方。這能確保瀏覽器已經將頁面所有的 HTML 元素都載入完成後，才開始執行 JavaScript，可有效避免 JS 因找不到頁面元素而出錯。

    * **方法二：外部腳本 (External Script) - 業界標準**
        * 將所有 JavaScript 程式碼儲存在一個獨立的 `.js` 檔案中（例如 `main.js`），再透過 `<script>` 標籤的 `src` 屬性引入。這是大型專案的標準作法，有助於程式碼的管理與重複利用。
        * **HTML 檔案 (`index.html`)**
            ```html
            <script src="main.js"></script>
            ```
        * **JavaScript 檔案 (`main.js`)**
            ```javascript
            console.log("這是從外部檔案執行的 Javascript");
            ```

---

* **3. 你的第一個指令：`console.log()`**
    * `console` 指的是瀏覽器的「**開發者主控台**」，一個專門給開發者查看訊息和除錯的隱藏視窗。
    * `log` 的意思是「紀錄」。
    * 所以 `console.log("想顯示的訊息");` 就是**「在主控台中記錄並顯示一則訊息」**。

    > [!IMPORTANT]
    > **如何打開瀏覽器主控台？**
    >
    > * 在網頁上按 `F12` 鍵。
    > * 或是在網頁上點擊右鍵，選擇「**檢查 (Inspect)**」，然後在跳出的視窗中找到「**Console**」或「**主控台**」分頁。

---

* **4. 綜合練習**
    * **目標成果**：在瀏覽器的「開發者主控台」中看到兩行文字訊息。
    ```html=
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 快速開始</title>
    </head>

    <body>
        <script>
            // 在主控台印出第一行訊息
            console.log("Hello Javascript");

            // 在主控台印出第二行訊息
            console.log("Hello 666");
        </script>
    </body>

    </html>
    ```
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/S10AtC1Lxe.png)
    :::
    
--- 

## 🎬 影片 13: JavaScript 變數、常數

### 🎯 本集重點 (Key Takeaways)
* **重點一：變數 (Variable) 是「資料的容器」**
    * 變數就像一個有名字的盒子，可以用來儲存、讀取和改變資料。
* **重點二：使用 `let` 宣告變數**
    * `let` 用來宣告一個「可以被改變」的變數。你可以隨時更新它裡面存放的資料。
* **重點三：使用 `const` 宣告常數**
    * `const` (Constant) 用來宣告一個「不能被改變」的常數。一旦賦值後，就無法再重新賦值，用來保護重要的資料不被意外修改。
* **重點四：現代開發的最佳實踐**
    * **優先使用 `const`**！只有當你確定這個值未來需要被改變時，才使用 `let`。這能增加程式碼的穩定性。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 什麼是變數 (Variable)？**
    * 在程式設計中，變數就像一個**貼有標籤的盒子**。
        * **`let x`**：就像是準備一個叫做 `x` 的空盒子。
        * **`x = 10`**：就是把 `10` 這個資料放進 `x` 這個盒子裡。
        * **`console.log(x)`**：就是打開 `x` 這個盒子，看看裡面裝了什麼。

---

* **2. 如何使用變數 (`let`)**
    * 它的生命週期包含「宣告」與「賦值」。

    * **Step 1: 宣告 (Declaration)**
        * 使用 `let` 關鍵字來「創造」一個變數。此時變數被宣告了，但裡面是空的，其值為 `undefined`。
        * **語法**：`let 變數名稱;`
        * **範例**：
            ```javascript
            let x;
            let name;
            console.log(x); // 會印出 undefined
            ```

    * **Step 2: 賦值 (Assignment)**
        * 使用 `=` 符號，將右邊的資料存放到左邊的變數中。
        * **語法**：`變數名稱 = 資料;`
        * **範例**：
            ```javascript
            let x;      // 宣告
            x = 5;      // 賦值 (第一次)
            console.log(x); // 印出 5
            
            x = "Hello"; // 重新賦值 (第二次)，let 允許我們隨時更新內容
            console.log(x); // 印出 "Hello"
            ```
    * **宣告與賦值可以寫在同一行：**
        ```javascript
        let message = "你好嗎？";
        console.log(message);
        ```

---

* **3. 什麼是常數 (`const`)**
    * 常數和變數很像，但它是一個**被鎖起來的盒子**。一旦放入資料後，就**再也不能更改**。
    * **特性**：
        1.  宣告時**必須同時賦值**。
        2.  賦值後**無法重新賦值**，試圖更改會直接報錯。
    * **語法**：
        ```javascript
        const 常數名稱 = 資料;
        ```
    * **範例**：
        ```javascript
        const PI = 3.14159; // PI 是個固定不變的值，很適合用常數
        console.log(PI);

        // PI = 3; // 這行程式碼會引發錯誤(TypeError)，因為常數不能被重新賦值
        ```

---

* **4. `let`, `const`, `var` 的選擇 (現代開發建議)**
    * **`const` (優先使用)**: 預設使用 `const`。這能確保資料不會在程式某處被意外修改，讓程式更穩定。
    * **`let`**: 只有當你「預期」這個變數的值未來會被改變時才使用，例如迴圈中的計數器。
    * **`var` (避免使用)**: 這是舊版的 JavaScript 語法。它有一些容易造成混淆的特性（例如作用域問題），在現代的專案開發中，已普遍**不推薦使用**。

---

- **5. 練習**
    ```html=
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 變數、常數</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>

    <body>
        <script>
            // 宣告變數：let 變數名稱
            let x;
            console.log(x);
            x=10; // 把資料放進變數中：宣告過的變數名稱=資料
            console.log(x);
            x=true;
            console.log(x);
            x=null;
            console.log(x);

            let abc="哈囉";
            console.log(abc);

            // 常數
            const z=100;
            console.log(z);
            // z=true; // 錯誤，不能更新常數裡面的資料
        </script>
    </body>

    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/SJnpgelIeg.png)
    :::
    
## 🎬 影片 14: JavaScript 運算符號

### 🎯 本集重點 (Key Takeaways)
* **重點一：運算符號的分類**
    * JavaScript 提供多種運算符號來處理資料，主要分為：**算術** (`+`, `-`, `*`)、**指定** (`=`, `+=`)、**比較** (`>`, `==`)、**邏輯** (`&&`, `||`, `!`) 等。
* **重點二：比較與邏輯是判斷的基礎**
    * 比較運算會回傳 `true` 或 `false` 的布林結果；邏輯運算則用來組合多個布林條件，是程式流程控制（如 `if` 判斷）的核心。
* **重點三：`prompt()` 用於使用者輸入**
    * `prompt()` 函數可以跳出一個對話框，讓使用者輸入文字，是簡單的互動方式。
* **重點四：`prompt()` 的陷阱 — 型態轉換**
    * **最關鍵的一點**：`prompt()` 接收到的任何輸入，都會被當作 **`String` (字串)** 型態。如果需要進行數學運算，必須先使用 `parseInt()` 或 `Number()` 將其轉換為 `Number` (數字) 型態。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 算術運算 (Arithmetic Operators)**
    * 用於執行基本的數學計算。
        * 加法：`+`
        * 減法：`-`
        * 乘法：`*`
        * 除法：`/`
        * 取餘數：`%` (例如 `7 % 3` 的結果是 `1`)

* **2. 指定運算 (Assignment Operators)**
    * 用於將資料「指定」或「賦值」給變數。
        * 基本指定：`=` (將右邊的值存到左邊的變數)
        * 複合指定：是算術運算與指定運算的簡寫，例如：
            * `x += 5;`  等同於 `x = x + 5;`
            * `x -= 3;`  等同於 `x = x - 3;`
            * `x *= 2;`  等同於 `x = x * 2;`

* **3. 比較運算 (Comparison Operators)**
    * 用於比較兩個值，結果永遠是 `true` 或 `false` 的布林值。
        * 大於：`>`
        * 小於：`<`
        * 大於等於：`>=`
        * 小於等於：`<=`
        * 等於：`==` (只比較值，不比較型態)
        * 全等於：`===` (值和型態都必須相同)
    > [!IMPORTANT]
    > **`==` vs `===` 的重要區別**
    > * `5 == "5"` 的結果是 `true`，因為 `==` 會自動轉換型態再比較值。
    > * `5 === "5"` 的結果是 `false`，因為兩者的「型態」不同 (一個是 Number，一個是 String)。
    > * **最佳實踐**：為了避免非預期的錯誤，**請一律使用 `===`** 進行相等比較。

* **4. 單元運算 (Unary Operators)**
    * 只需一個運算元即可操作。
        * 遞增 (變數值加 1)：`++` (例如 `x++`)
        * 遞減 (變數值減 1)：`--` (例如 `x--`)
        * 布林反運算 (NOT)：`!` (例如 `!true` 結果是 `false`)

* **5. 邏輯運算 (Logical Operators)**
    * 用於組合多個布林條件。
    * **且 (AND)：`&&`**
        * 兩邊都必須是 `true`，結果才是 `true`。
        | A | B | A && B |
        | :---: | :---: | :---: |
        | `true` | `true` | `true` |
        | `true` | `false`| `false`|
        | `false`| `true` | `false`|
        | `false`| `false`| `false`|
    * **或 (OR)：`||`**
        * 只要其中一邊是 `true`，結果就是 `true`。
        | A | B | A \|\| B |
        | :---: | :---: | :---: |
        | `true` | `true` | `true` |
        | `true` | `false`| `true` |
        | `false`| `true` | `true` |
        | `false`| `false`| `false`|

---

* **6. 與使用者互動：`prompt()` 函數**
    * `prompt()` 會在瀏覽器跳出一個對話框，讓使用者可以輸入內容。

    * **語法**：
        ```javascript
        let userInput = prompt("這是提示文字", "這是輸入框的預設值");
        ```

    * **回傳值特性**：
        * **(陷阱！)** 無論使用者輸入數字還是文字，`prompt()` 的回傳值**永遠都是 `String` (字串) 型態**。
        * 如果使用者按下「取消」，則回傳 `null`。
    
    * **型態轉換**：
        * 因為回傳的是字串，若要進行數學運算，必須先將其轉換為數字。
        * **`parseInt(字串)`**：將字串轉換為**整數**。
        * **`parseFloat(字串)`**：將字串轉換為包含小數的**浮點數**。
        * **`Number(字串)`**: 較嚴格的轉換函式。

        ```javascript
        let ageString = prompt("請輸入你的年齡", "18"); // ageString 會是 "18" (字串)
        let ageNumber = parseInt(ageString); // ageNumber 會是 18 (數字)
        console.log(ageNumber + 2); // 結果是 20
        console.log(ageString + 2); // 結果是 "182" (字串串接)
        ```

---

* **7. 綜合練習**

    ```html=
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 運算符號</title>
    </head>
    <body>
        <script>
            // 算術運算：+, -, *, /, %
            let x = 7 % 3; // 7 除以 3 的餘數是 1
            console.log("7 % 3 =", x);

            // 指定運算：=, +=, -=. *=, /=, %=
            x += 1; // x = x + 1 => 1 + 1 = 2
            console.log("x += 1 後:", x);
            // x -= 4; // x = x - 4 => 2 - 4 = -2
            // console.log("x -= 4 後:", x);

            // 比較運算：>, <, >=, <=, ==, ===
            let isEqual = ("Hello" === "Hello"); // 使用 === 比較
            console.log("'Hello' === 'Hello':", isEqual);

            // 單元運算：!, ++, --
            let isNotEqual = !isEqual; // !true => false
            console.log("!isEqual:", isNotEqual);
            x = 3;
            x++; // x = x + 1 => 3 + 1 = 4
            console.log("x++ 後:", x);
            
            // 邏輯運算：&&, ||
            let test = true && false;
            console.log("true && false:", test);
            test = true || false;
            console.log("true || false:", test);

            console.log("--- 使用者輸入練習 ---");
            // 要求使用者輸入：prompt(提示詞, 預設值)
            let n1_str = prompt("請輸入第一個數字", "5");
            let n2_str = prompt("請輸入第二個數字", "10");

            // 重要！將從 prompt 得到的「字串」轉成「數字」
            let n1_num = parseInt(n1_str);
            let n2_num = parseInt(n2_str);

            // let result = n1_str * n2_str; // 這是不可靠的作法，雖然JS會嘗試轉換，但不是好習慣
            let result = n1_num * n2_num; // 這是正確的作法
            
            console.log("使用者輸入的計算結果:", result);
        </script>
    </body>
    </html>
    ```

    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/r1MIUMZIlx.png)
    ![image](https://hackmd.io/_uploads/BJCIIG-Ixg.png)
    ![image](https://hackmd.io/_uploads/Byow8MbLgx.png)
    :::
    
---

## 🎬 影片 15: JavaScript 流程控制：判斷式

### 🎯 本集重點 (Key Takeaways)
* **重點一：流程控制 (Flow Control)**
    * 程式碼預設是由上到下循序執行，而「流程控制」能讓我們根據不同的「條件」，來決定要執行哪一段程式碼，讓程式擁有做決定的能力。
* **重點二：`if` 是判斷的基礎**
    * `if (條件)` 會判斷括號中的條件是否為 `true`。如果是，才會執行緊接著的大括號 `{}` 程式區塊。
* **重點三：`else` 提供另一條路**
    * 當 `if` 的條件不成立 (為 `false`) 時，可以透過 `else` 提供一個「否則」的執行路徑。
* **重點四：`else if` 建立多重條件**
    * 當有「多選一」的情境時，可以使用 `else if` 來串連多個判斷條件，程式會由上到下逐一檢查，直到找到第一個成立的條件去執行。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 為什麼需要流程控制？**
    * 如果沒有流程控制，程式碼就像一條單行道，只能從頭走到尾。而流程控制就像在路上設置了各種**岔路和紅綠燈**，讓程式可以根據不同狀況，走向不同的道路，執行不同的任務。
    * **程式區塊 (`{ }`)**: 在流程控制中，大括號 `{}` 用來包裹一段特定的程式碼，形成一個獨立的區塊。當條件成立時，就會執行這個區塊內的**所有**程式。
        ```javascript
        {
            // 這是一個程式區塊
            console.log("Hello");
            console.log("World");
        }
        ```

---

* **2. `if` 判斷式的三種基本結構**

    * **結構一：`if` (如果...就...)**
        * 最單純的判斷，只有一個條件，符合了才做事，不符合就直接跳過。
        * **語法**：
            ```javascript
            if (布林值) {
                // 如果布林值為 true，就執行這裡
            }
            ```
        * **比喻**：如果「外面下雨」，就「帶上雨傘」。

    * **結構二：`if...else` (如果...就...，否則...)**
        * 提供「二選一」的路徑。條件成立走 `if` 的路，不成立就走 `else` 的路。
        * **語法**：
            ```javascript
            if (布林值) {
                // 如果布林值為 true，執行這裡
            } else {
                // 如果布林值為 false，執行這裡
            }
            ```
        * **比喻**：如果「錢包有錢」，就「吃大餐」，否則就「吃泡麵」。

    * **結構三：`if...else if...else` (多選一)**
        * 用於處理多種可能的情況。它會從上到下逐一檢查條件，一旦找到第一個符合的，就會執行對應的區塊，然後**跳過後面所有剩餘的 `else if` 和 `else`**。
        * **語法**：
            ```javascript
            if (條件一) {
                // 如果條件一為 true，執行這裡
            } else if (條件二) {
                // 如果條件一為 false，且條件二為 true，執行這裡
            } else if (條件三) {
                // 如果前兩者皆為 false，且條件三為 true，執行這裡
            } else {
                // 如果以上所有條件都為 false，執行這裡
            }
            ```
        * **比喻**：如果「考 100 分」，就「買遊戲機」；或者如果「考 80 分以上」，就「吃大餐」；否則就「繼續唸書」。

---

* **3. 綜合練習**
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 流程控制：判斷式</title>
    </head>
    <body>
        <script>
            // 1. 透過 prompt 取得使用者輸入的「字串」
            let moneyString = prompt("要領多少錢?", "5000");

            // 2. 使用 parseInt 將字串轉換成數字
            let money = parseInt(moneyString);

            // 3. 開始進行判斷
            // 增加一個判斷，如果使用者輸入的不是數字 (轉換後變成 NaN)，就給出提示
            if (isNaN(money)) {
                console.log("請輸入有效的數字！");
            } else if (money < 100) {
                console.log("金額太少了，至少要領 100 元。");
            } else if (money <= 100000) { // 比較運算的結果 (true/false) 會被當作 if 的條件
                console.log("OK，領款成功！");
            } else { // 如果以上條件都不符合，就會執行這裡
                console.log("金額太多了，不能領超過 10 萬元。");
            }

            console.log("判斷式結束，繼續執行後續程式。");
        </script>
    </body>
    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/rySmDGZUee.png)
    ![image](https://hackmd.io/_uploads/B1EEwfWLxx.png)
    :::
    
---    

## 🎬 影片 16: JavaScript 流程控制：迴圈

### 🎯 本集重點 (Key Takeaways)
* **重點一：迴圈 (Loop) 的用途**
    * 迴圈的核心目標是**重複執行**某一段程式碼區塊，讓我們能用精簡的程式碼處理大量、重複性的任務。
* **重點二：`while` 迴圈**
    * `while` 迴圈會在「條件為 `true`」的情況下，不斷重複執行。它適合用在**不知道確切要跑幾次**，只知道「直到...為止」的情境。
* **重點三：`for` 迴圈**
    * `for` 迴圈將「初始狀態、結束條件、狀態更新」三個迴圈要素整合在一行，結構更清晰，特別適合用在**已知要跑固定次數**的情境。
* **重點四：避免「無窮迴圈」**
    * 寫迴圈時最重要的事，就是要確保「結束條件」最終會有變成 `false` 的一天。否則迴圈會永不停止，導致程式或瀏覽器當機。
* **重點五：for...of 迴圈(新知)**
    * 專為遍歷**可迭代物件**（如陣列、字串、Map、Set 等）的「值」而設計，語法簡潔，直接取得元素值。
* **重點六：forEach 方法(新知)**
    * 陣列內建的方法，讓我們能對陣列中的每個元素執行一次回呼函式，語法直觀，常取代傳統 `for` 迴圈來處理陣列元素。
* **重點七：for...in 迴圈(新知)**
    * 主要用於遍歷物件的**可列舉屬性名稱（鍵值）**。它會依序回傳物件中每個屬性的字串鍵值。
    
### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 為什麼需要迴圈？**
    * 想像一下，如果沒有迴圈，當我們要印出 100 次 "Hello"，就必須手動複製貼上 100 行 `console.log("Hello")`。
    * 迴圈讓我們可以下達一個更聰明的指令：「**只要**印出的次數還沒到 100 次，**就**繼續印 "Hello"」，這就是程式自動化的威力。

---

* **2. `while` 迴圈**
    * `while` 的意思是「當...的時候」。它會先檢查括號中的條件，如果為 `true`，就執行一次 `{}` 區塊中的程式碼，然後再回到開頭重新檢查條件，直到條件變為 `false` 才停止。

    * **基本語法**：
        ```javascript
        while (布林值) {
            // 如果布林值為 true，重複執行這個程式區塊
            // 執行完畢後，跳到迴圈開頭，重新再來一次
        }
        ```

    * **`while` 迴圈的組成三要素**：
        1.  **初始狀態**：迴圈開始前的計數器或狀態。 (`let n = 0;`)
        2.  **結束條件**：放在 `while()` 中的判斷式。 (`n < 3`)
        3.  **狀態更新**：在區塊內改變狀態，以確保迴圈能朝著結束條件邁進。 (`n++;`)
    
    * **基本範例**：
        ```javascript
        let n = 0; // 1. 初始狀態
        while (n < 3) { // 2. 結束條件
            console.log(n);
            n++; // 3. 狀態更新 (如果沒有這行，會造成無窮迴圈！)
        }
        // 執行順序：
        // n=0, 0<3, 印出0, n變1
        // n=1, 1<3, 印出1, n變2
        // n=2, 2<3, 印出2, n變3
        // n=3, 3<3 (false), 迴圈結束
        ```

---

* **3. `for` 迴圈**
    * `for` 迴圈可以看作是 `while` 迴圈的「精簡版」，它把「初始狀態、結束條件、狀態更新」這三要素都寫在同一行的小括號中，讓程式碼更簡潔、一目了然。

    * **基本語法**：
        ```javascript
        for (初始狀態; 結束條件; 狀態更新) {
            // 如果結束條件為 true，執行這個程式區塊
        }
        ```

    * **`for` vs `while` 範例對照**：
        * 以下兩個迴圈做的事情完全一樣，但可以看出 `for` 迴圈的寫法更為緊湊。
        * **while 迴圈寫法**
            ```javascript
            let n = 0;
            while (n < 3) {
                console.log(n);
                n++;
            }
            ```
        * **for 迴圈寫法**
            ```javascript
            for (let n = 0; n < 3; n++) {
                console.log(n);
            }
            ```

---

* **4. `for...of` 迴圈**
    * `for...of` 迴圈是 ES6 (ECMAScript 2015) 引入的一種新式迴圈，專門用於遍歷任何**可迭代物件 (iterable objects)** 的元素值。這包括陣列 (Arrays)、字串 (Strings)、Map、Set 等。它的語法比傳統的 `for` 迴圈更簡潔，且能直接取得每個元素的值，而不需要透過索引。
    * 基本語法：
        ```javascript
        for(let 變數 of 可迭代物件) {
            // 對於可迭代物件中的每個元素值，執行這個程式區塊   
        }
        ```
    * 優點
        * **簡潔易讀**：直接取得元素值，不需要處理索引或計數器。
        * **適用範圍廣**：適用於所有可迭代物件，不限於陣列。
    * 範例：
        ```javascript
        console.log("--- for...of 迴圈範例 ---");

        const fruits = ["apple", "banana", "cherry"];
        for (let fruit of fruits) {
            console.log(fruit); // 依序印出 "apple", "banana", "cherry"
        }

        const myString = "Hello";
        for (let char of myString) {
            console.log(char); // 依序印出 "H", "e", "l", "l", "o"
        }

        // 注意：for...of 不能直接用於遍歷物件的屬性，因為物件本身不可迭代
        const myObject = { a: 1, b: 2 };
        // for (let key of myObject) { // 會報錯：myObject is not iterable
        //     console.log(key);
        // }
        // 如果要遍歷物件屬性，可以使用 for...in 或 Object.keys()/values()/entries()
        ```
    
---

* **5. `Array.prototype.forEach()` 方法**
    * `forEach()` 是 JavaScript 陣列 (Array) 的一個內建方法，它允許你對陣列中的每個元素執行一次提供的回呼 (callback) 函式。這是一種處理陣列元素的簡潔且功能強大的方式，尤其適合當你不需要中斷迴圈或改變原始陣列時。
    * 基本語法：
        ```javascript
        array.forEach(function(currentValue, index, array) {
            // 對每個元素執行的程式碼
        });
        ```   
        * currentValue：當前處理的元素值。
        * index (可選)：當前處理元素的索引。
        * array (可選)：`forEach()`方法正在操作的陣列本身。
    
    * 優點：
        **語法直觀**：清晰地表達了對每個陣列元素執行某個操作的意圖。

        **函數式風格**：與許多其他陣列方法（如 map, filter）相輔相成，鼓勵更函數式的程式設計。

        **不需要管理計數器**：自動為每個元素調用回呼函式。
        
    * 限制：
        * 不能使用 `break` 或`continue：forEach()` 無法像傳統 for 迴圈那樣提前跳出或跳過迭代。

        * 沒有回傳值：`forEach()` 方法本身沒有回傳值 (回傳 undefined)，它主要用於執行副作用 (side effects)，例如印出內容或修改外部變數。如果需要產生一個新陣列，通常會使用 `map()` 或 `filter()`。

    * 範例：
        ```javascript
        console.log("--- forEach 方法範例 ---");

        const numbers = [10, 20, 30, 40];

        // 只使用元素值
        numbers.forEach(function(num) {
            console.log(`數字是: ${num}`);
        });

        // 同時使用元素值和索引
        numbers.forEach(function(num, index) {
            console.log(`索引 ${index} 的數字是: ${num}`);
        });

        // 箭頭函式簡寫
        numbers.forEach((num, index) => {
            console.log(`[${index}] => ${num}`);
        });

        // 計算陣列總和
        let totalSum = 0;
        numbers.forEach(function(num) {
            totalSum += num;
        });
        console.log("陣列總和:", totalSum); // 印出 100
        ```
---

* **6. `for...in` 迴圈**
    * `for...in` 迴圈主要用於遍歷物件的可列舉屬性名稱 (property names)。它會依序回傳物件中每個屬性的字串鍵值 (key)。

    * **重要提示：** 雖然 `for...in` 也可以用來遍歷陣列索引，但不推薦這樣做，因為它會遍歷所有可列舉的屬性（包括繼承的屬性），可能會導致非預期的行為。遍歷陣列請優先使用 `for`、`for...of` 或 `forEach`。
    * 基本語法：
        ```javascript
        for (let key in object) {
            // 對於物件中的每個可列舉屬性，執行這個程式區塊
            // key 是屬性名稱 (字串)
        }
        ```   
    
    * 優點：
        **遍歷物件屬性**：是遍歷物件自身屬性鍵值的便捷方式。
        
    * 限制：
        * **遍歷的是鍵 (key)**：不是值，需要用 `object[key]` 來取得對應的值。

        * **包含繼承的屬性**：會遍歷原型鏈上可列舉的屬性，如果不想遍歷繼承的屬性，需要搭配 `hasOwnProperty()` 方法。

        * **順序不保證**：在舊版 JavaScript 中，遍歷屬性的順序不保證。雖然現代 JavaScript 引擎對數字鍵值有排序，但對於其他鍵值仍不保證。

    * 範例：
        ```javascript
        console.log("--- for...in 迴圈範例 ---");

        const person = {
            name: "Alice",
            age: 30,
            city: "Taipei"
        };

        for (let prop in person) {
            // prop 是屬性名稱 (字串)，例如 "name", "age", "city"
            console.log(`${prop}: ${person[prop]}`);
        }
        // 輸出：
        // name: Alice
        // age: 30
        // city: Taipei

        // 搭配 hasOwnProperty() 避免遍歷繼承屬性
        for (let prop in person) {
            if (person.hasOwnProperty(prop)) {
                console.log(`自有屬性 - ${prop}: ${person[prop]}`);
            }
        }

        // 不推薦用 for...in 遍歷陣列，因為它遍歷的是索引 (字串)，且可能有非預期行為
        const arr = ["a", "b", "c"];
        for (let index in arr) {
            console.log(`陣列索引 (字串): ${index}, 值: ${arr[index]}`);
        }
        // 輸出 (注意索引是字串類型)：
        // 陣列索引 (字串): 0, 值: a
        // 陣列索引 (字串): 1, 值: b
        // 陣列索引 (字串): 2, 值: c
        // 建議對陣列使用 for、for...of 或 forEach。
        ```

---

* **7. 綜合練習**

    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 流程控制：迴圈</title>
    </head>
    <body>
        <script>
            console.log("--- while 迴圈練習 ---");
            let n = 0;
            while (n < 5) {
                console.log(n);
                n++;
            }

            console.log("--- for 迴圈練習 (印出 2 到 10 的偶數) ---");
            for (let i = 2; i <= 10; i += 2) {
                console.log(i);
            }

            console.log("--- 計算 1+2+...+10 的結果 ---");
            
            // 解法一：數學家的方法 (高斯公式)
            let mathResult = (1 + 10) * 10 / 2;
            console.log("數學解法:", mathResult);

            // 解法二：程式設計師的方法 (用迴圈累加)
            let o = 1;     // 用來追蹤 1, 2, 3, ..., 10
            let total = 0; // 用來存放累加的總和，初始為 0
            
            while (o <= 10) {
                // total = mathResult + o; // 這是錯誤的邏輯！這會變成用固定的 55 去加 o
                total = total + o; // 正確邏輯：將「目前的總和」加上「當前的數字o」，再存回「總和」中
                // 更簡潔的寫法是：total += o;
                o++;
            }
            console.log("迴圈解法:", total);
        </script>
    </body>
    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/BJB9K_bLex.png)
    :::
    
---

## 🎬 影片 17: JavaScript 流程控制：迴圈指令

### 🎯 本集重點 (Key Takeaways)
* **重點一：進階迴圈控制**
    * `break` 和 `continue` 是用來在迴圈執行過程中，進行更精細流程控制的兩個關鍵指令。
* **重點二：`break` 是「緊急出口」**
    * `break` 會**立即且強制地終止**整個迴圈的執行，程式會直接跳到迴圈外面的下一行程式碼。
* **重點三：`continue` 是「跳過按鈕」**
    * `continue` 會**立即停止「當前」這一圈**的執行，並直接跳到迴圈的開頭，開始進行**下一圈**的條件判斷。
* **重點四：必須在迴圈內使用**
    * 這兩個指令都只能存在於 `while`、`for` 等迴圈的程式區塊中，否則會產生語法錯誤。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. `break` 指令：強制終止迴圈**
    * **用途**：當我們在迴圈中「找到」了我們要的東西，或達成了某個特殊條件，不再需要繼續執行後續的迴圈時，就可以使用 `break` 來提早結束，以提升程式效率。
    * **比喻**：像是在一疊 100 張的考卷中找「張三」的考卷。當你在第 30 張找到時，你就可以直接 `break` 停止尋找，不需要再看後面剩下的 70 張。

    * **使用範例**：
        ```javascript
        let n = 0;
        while (n < 5) {
            if (n === 3) {
                console.log("找到 3 了，強制結束迴圈！");
                break; // 當 n 等於 3 時，跳出 while 迴圈
            }
            console.log(n);
            n++;
        }
        console.log("迴圈已經結束。");
        // 輸出結果：
        // 0
        // 1
        // 2
        // 找到 3 了，強制結束迴圈！
        // 迴圈已經結束。
        ```

---

* **2. `continue` 指令：跳過此圈，進入下一圈**
    * **用途**：當迴圈跑到某個項目，而這個項目不符合我們想處理的條件時，可以使用 `continue` 來略過它，直接處理下一個項目。
    * **比喻**：像是在處理一籃水果，你的任務是「榨汁」，但你只想處理橘子和檸檬。當你拿到一顆「蘋果」時，你就 `continue` 跳過它，直接去拿下一顆水果，而不用停止整個榨汁的工作。

    * **使用範例**：(已修正 `fot` 錯字)
        ```javascript
        for (let n = 0; n < 5; n++) {
            if (n === 2) {
                console.log("數字 2 不想印，跳過！");
                continue; // 當 n 等於 2 時，跳過本次的 console.log(n)
            }
            console.log(n);
        }
        // 輸出結果：
        // 0
        // 1
        // 數字 2 不想印，跳過！
        // 3
        // 4
        ```

---

* **3. 綜合練習**
* 
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 流程控制：迴圈指令</title>
    </head>
    <body>
        <script>
            console.log("--- break 指令練習 ---");
            // 原本要跑到 n < 5，但我們在 n=3 時就強制中斷
            let n = 0;
            while(n < 5){
                if(n === 3){
                    break; // 當 n 等於 3，強制結束迴圈
                }
                console.log(n);
                n++;
            }

            console.log("--- continue 指令練習 (只印出奇數) ---");
            // 印出 0 到 4 之間的奇數
            for(let i = 0; i < 5; i++){
                // 如果 i 是偶數 (i 除以 2 的餘數為 0)
                if(i % 2 === 0){
                    continue; // 跳過當前迴圈，不執行下面的 console.log
                }
                // 只有當 i 是奇數時，這行才會被執行
                console.log(i);
            }
        </script>
    </body>
    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/B1jpXOMUxl.png)
    :::
    
---

## 🎬 影片 18: JavaScript 函式基礎

### 🎯 本集重點 (Key Takeaways)
* **重點一：函式 (Function) 是可重複使用的「程式碼包裹」**
    * 函式讓我們能將一段特定的程式碼包裝起來並給它一個名字，之後就可以透過呼叫這個名字來重複執行，避免寫重複的程式碼。
* **重點二：先「定義」，後「呼叫」**
    * 使用函式的流程分為兩步：先用 `function` 關鍵字建立函式（定義要做的事），然後再透過函式名稱搭配括號 `()` 來執行它（呼叫）。
* **重點三：參數 (Parameters) 是函式的「接口」**
    * 參數讓函式變得更有彈性。我們在定義函式時設定參數（佔位符），在呼叫時傳入實際的資料（引數），函式就可以根據我們傳入的不同資料，執行對應的任務。
* **重點四：`return` 讓函式能「回傳結果」**
    * `return` 是函式最重要的功能之一，它能將函式內部的運算結果「送出來」，讓我們可以在函式外部接住這個結果，並儲存到變數或進行後續運用。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 為什麼需要函式 (Function)？**
    * 函式是組織與建構程式碼的基本單位，就像是食譜或工具機。
    * **比喻**：我們可以定義一個叫做 `makeJuice` (打果汁) 的函式。
        * **定義函式**：就像是設計一台果汁機，設定好它需要「水果」當作材料，以及它內部的運作是「榨汁」。
        * **呼叫函式**：就是實際使用這台果汁機。`makeJuice("蘋果")` 就會得到蘋果汁，`makeJuice("芭樂")` 就會得到芭樂汁。我們不需要每次都重新打造一台果汁機。
    * **優點**：提高程式碼的**可讀性**、**可維護性**與**可重複使用性**。

---

* **2. 函式的基本結構：從無參數到多參數**
    * 函式內部的程式碼在被呼叫前，是不會執行的。根據需不需要外部資料，函式可以分為幾種類型：

    * **A. 無參數函式 (No-Parameter Function)**
        * **說明**：這是最單純的函式，它不需要任何外部資訊就能獨立完成一件固定的事情。
        * **比喻**：像是一個只有「啟動」按鈕的機器，每次按下，都執行一模一樣的流程。
        * **範例**：
            ```javascript
            // 定義一個無參數函式，用來打招呼
            function sayHello() {
                console.log("Hello");
                console.log("World");
            }

            // 呼叫函式，括號中不需要放任何東西
            sayHello(); // 會印出 Hello 和 World
            sayHello(); // 再呼叫一次，做同樣的事
            ```

    * **B. 單一參數函式 (Single-Parameter Function)**
        * **說明**：讓函式在執行時，可以接收「一項」從外部傳入的資料，讓函式變得更有彈性。
        * **比喻**：像是一台飲料機，你投入的「選項」（引數）決定了掉出來的「飲料」（函式執行的結果）。
        * **範例**：
            ```javascript
            // 定義一個函式，它有一個參數(Parameter)叫做 msg
            function show(msg) {
                console.log("您傳入的訊息是:", msg);
            }

            // 呼叫函式，並傳入不同的引數(Argument)
            show("你好");       // msg 的值會是 "你好"
            show(true);       // msg 的值會是 true
            show(12345);      // msg 的值会是 12345
            ```
            > **術語小百科**：
            > * **參數 (Parameter)**：定義函式時，寫在括號中的「佔位符變數」，如 `msg`。
            > * **引數 (Argument)**：呼叫函式時，實際傳入的「真實資料」，如 `"你好"`。


    * **C. 多個參數函式 (Multi-Parameter Function)**
        * **說明**：最常見的函式類型，可以一次接收「多項」外部資料，來進行更複雜的運算。
        * **比喻**：像是一台專業的咖啡機，你可以同時調整「咖啡豆種類、水量、奶量」等多個參數，來客製化你想要的咖啡。
        * **範例**：
            ```javascript
            // 定義一個函式，它有 n1 和 n2 兩個參數
            function add(n1, n2) {
                let result = n1 + n2;
                console.log("計算結果:", result);
            }

            // 呼叫函式，並依序傳入兩個引數
            add(3, 4);              // 印出 7
            add(10, 5);             // 印出 15
            add("Hello", "World");  // 印出 "HelloWorld"
            ```
---

* **3. 讓函式「回傳」結果 (`return`)**
    * `console.log()` 只是把結果「印」在主控台給開發者看，但程式本身無法取得這個結果做後續運用。
    * `return` 關鍵字能將函式處理完的結果「送出來」，這才是函式最有價值的地方。

    * **範例**：
        ```javascript
        function add(n1, n2) {
            let result = n1 + n2;
            return result; // 將計算結果回傳出去
            // console.log("這行不會被執行"); // return 後面的程式碼都不會執行
        }

        // 呼叫函式，並用一個變數去「接住」回傳的結果
        let sum = add(8, 2); 

        console.log(sum); // 印出 10
        console.log(sum * 5); // 可以拿回傳的結果做後續運算，印出 50
        ```

---

* **4. 函式的兩種定義方式**
    * **方法一：函式宣告 (Function Declaration)**
        * 這是最標準的寫法，以 `function` 關鍵字開頭。
        ```javascript
        function 函式名稱(參數列表) {
            // ...
        }
        ```
    * **方法二：函式表達式 (Function Expression)**
        * 這種寫法是宣告一個變數或常數，並將一個「匿名函式」賦值給它。
        ```javascript
        let 函式名稱 = function(參數列表) {
            // ...
        }; // 習慣上，表達式的結尾會加上分號
        ```
    > [!IMPORTANT]
    > **兩者的關鍵差異：提升 (Hoisting)**
    > * **函式宣告**：會被「提升」到程式碼的最頂端。意思是，你可以在宣告函式**之前**就呼叫它。
    > * **函式表達式**：不會被提升。你必須在宣告了這個變數**之後**，才能透過變數名稱來呼叫它。
    > * **建議**：為求程式碼清晰，養成「先定義再呼叫」的好習慣，可以減少很多不必要的混亂。

---

* **5. 把 function 當作值**
    * JavaScript 函式是一種「一級公民」（first-class citizen），這表示函式可以像其他資料型別（如數字、字串）一樣被當作值來傳遞，例如作為另一個函式的參數。
    ```javascript
    function add(x, y){
        return x + y;
    }

    function mult(x, y){
        return x * y;
    }
    
    function printResult(x, y, fn){
        console.log(`Result：${fn(x, y)}`); // 使用模板字串更清晰
    }

    // 範例：傳遞一個加法函式
    printResult(10, 5, add); // 輸出 Result：15

    // 範例：傳遞一個乘法函式
    printResult(10, 5, mult); // 輸出 Result：50
    ```

---

* **6. 綜合練習**
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 流程控制：函式基礎</title>
    </head>
    <body>
        <script>
            // === 練習 1：無參數函式 ===
            // 定義一個叫做 test 的函式
            function test() {
                console.log("Hello");
                console.log("World");
            }
            // 連續呼叫兩次
            test();

            // === 練習 2：單一參數函式 ===
            // 定義一個叫做 show 的函式，它有一個參數叫 message
            function show(message){
                console.log("您傳入的訊息是:", message);
            }
            show("Hello");
            show(10);

            // === 練習 3：多參數與 return ===
            // 定義一個做除法的函式，並使用 return 回傳結果
            function divide(num1, num2){
                return num1 / num2;
            }
            // 呼叫函式並用變數接收回傳值
            let divisionResult = divide(10, 5);
            console.log("10 / 5 的結果是:", divisionResult);

            // === 練習 4：函式表達式 ===
            // 使用函式表達式定義一個做加法的函式
            let addExpression = function(num1, num2){
                console.log("加法結果是:", num1 + num2);
            };
            addExpression(3, 2);
            addExpression("Hello", "World");
        </script>
    </body>
    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/H1UJT5-8ll.png)
    :::
    
---

## 🎬 影片 19: JavaScript 函式回傳值

### 🎯 本集重點 (Key Takeaways)
* **重點一：`return` 是函式的「出口」**
    * `return` 的核心功能是將函式內部的運算結果「送出去」，讓函式外部的程式可以接收並利用這個結果。
* **重點二：`return` 會立即中止函式**
    * 一旦函式執行到 `return` 這一行，整個函式會立刻結束，`return` 後面的所有程式碼都不會被執行。
* **重點三：一個函式只會有一個回傳結果**
    * 雖然函式內可以有多個 `return` 敘述（例如在 `if/else` 中），但對於任何一次的函式呼叫，只會有「一個」`return` 會被執行，並送出一個值。
* **重點四：沒有 `return` 就回傳 `undefined`**
    * 如果一個函式從頭到尾都沒有執行到任何 `return` 敘述就結束了，它會自動回傳一個預設值：`undefined`。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 為什麼需要回傳值？`console.log` vs `return`**
    * 在之前的課程中，我們常在函式裡用 `console.log()`，但它只是把結果「印」在主控台給開發者看，程式本身無法利用這個印出來的結果。
    * **比喻**：
        * **`console.log()`**：像是果汁機上的一個顯示面板，它會顯示「蘋果汁已完成」，但你拿不到果汁。
        * **`return`**：則是果汁機的「出汁口」，它會把真正的「蘋果汁」送出來，你可以把它裝進杯子（存入變數）、拿去給別人喝（傳給另一個函式），或做其他運用。

    * 因此，函式的學習重點可以歸納為三大塊：
        1.  **建立與呼叫**：學會定義與執行函式。
        2.  **參數運用**：學會如何將資料「傳入」函式。
        3.  **回傳值運用**：學會如何將結果從函式中「傳出」。

---

* **2. `return` 的運作機制與語法**
    * `return` 的作用是將資料從**函式內部**，傳回到當初**呼叫函式的位置**。
        ![image](https://hackmd.io/_uploads/ByuHDdMUxx.png =60%x)

    * **語法一：回傳指定的值**
        * `return` 後方可以跟上任何型態的資料（數字、字串、布林值，甚至是物件或另一個函式）。
        ```javascript
        function 函式名稱(參數列表) {
            // ...
            return 回傳值;
        }
        ```
        * 函式最後回傳什麼，只跟 `return` 後面的值有關。
            ![image](https://hackmd.io/_uploads/r18odOMUlx.png =60%x)
        * 回傳出來的值，可以被存放到變數中。
            ![image](https://hackmd.io/_uploads/HkgeMtOMLll.png =60%x)

    * **語法二：提早結束函式**
        * 單獨使用 `return;`，或函式跑到結尾都沒有 `return`，都會讓函式回傳 `undefined`。
        * 這種寫法的主要用途，是在函式中途的某個條件下，**提早結束函式**的執行。
        ```javascript
        function 函式名稱(參數列表) {
            // ...
            if (某個條件) {
                return; // 條件成立，函式到此為止，回傳 undefined
            }
            // ... 後續程式碼在條件成立時不會被執行
        }
        ```

---

* **3. 設計有意義的回傳值**
    * 一個設計良好的函式，通常會有明確的單一功能，並回傳一個有意義、可預期的結果。
    * 例如，一個檢查年齡的函式，回傳 `true` 或 `false`，就比直接在函式內印出文字要好用得多，因為外部程式可以根據這個布林值做後續的判斷。
    ![image](https://hackmd.io/_uploads/SybaFOzLgx.png =60%x)
    * **範例**：
    ```javascript
    // 設計一個檢查是否為正數的函式
    function isPositive(number) {
        if (number > 0) {
            return true;
        } else {
            return false;
        }
    }

    let checkResult = isPositive(10); // checkResult 會是 true
    if (checkResult) {
        console.log("這是一個正數");
    }
    ```

---

* **4. 綜合練習**

    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 函式回傳值</title>
    </head>
    <body>
        <script>
            // === 練習 1：return 用來結束函式並回傳值 ===
            function test() {
                console.log("函式內部：印出 Hello");
                return true; // 設定回傳值為 true，並結束函式
                console.log("這行永遠不會被執行");
            }

            // 呼叫 test()，它會執行 console.log("Hello")，然後「變成」它回傳的 true
            // 最後，這個 true 被存到 value 變數中
            let value = test(); 
            
            // 印出 value 變數的內容
            console.log("函式外部：接收到的回傳值是", value);

            console.log("--- 分隔線 ---");

            // === 練習 2：利用回傳值做後續運算 ===
            function divide(n1, n2) {
                let result = n1 / n2;
                // 在函式內部印出計算過程
                console.log("函式內部：計算結果是", result);
                // 將計算結果回傳出去
                return result;
            }

            // 呼叫 divide(4, 2)，函式內部印出 2，然後回傳 2
            // 這個回傳的 2 會被存到 ans 變數中
            let ans = divide(4, 2); 
            
            // 現在 ans 的值是 2，可以拿來做後續運算
            ans = ans * 10;
            
            // 印出最終運算結果
            console.log("函式外部：拿回傳值做後續運算得到", ans);
        </script>
    </body>
    </html>
    ```
    
    ::: spoiler 成果展示
    ![image](https://hackmd.io/_uploads/HyXd3_zLel.png)
    :::

---

## 🎬 影片 20: JavaScript 物件基礎

### 🎯 本集重點 (Key Takeaways)
* **重點一：物件 (Object) 是「資料與功能的集合體」**
    * 物件就像一個多功能的「工具箱」，可以將多個相關的「資料（屬性）」和「功能（方法）」打包在一起，方便管理與使用。
* **重點二：`{}` 物件字面值是建立物件的標準方式**
    * 在現代 JavaScript 中，使用大括號 `{}` 搭配 `鍵:值` 的「物件字面值 (Object Literal)」語法，是建立物件最快、最清晰、也最推薦的方式。
* **重點三：使用「點 `.`」來存取成員**
    * 我們可以透過「點 `.`」運算子來讀取、設定物件的屬性，或呼叫物件的方法。例如：`person.name`、`person.talk()`。
* **重點四：`this` 關鍵字代表「物件本身」**
    * 在一個物件的方法（函式）中，`this` 這個關鍵字就代表了「呼叫這個方法的物件本身」，讓方法可以存取到自己物件內的其他屬性。

### 📝 詳細筆記與心得 (Notes & Reflections)

* **1. 為什麼需要物件 (Object)？**
    * 在之前的學習中，我們的資料都是零散的，例如：
        ```javascript
        let personName = "小明";
        let personAge = 18;
        ```
    * 如果要描述同一個人的多個特徵，這樣會產生很多變數，不好管理。
    * **物件**就是為了解決這個問題而生。它讓我們可以將所有相關的資料，都放進一個大的「容器」中。
    * **比喻**：
        * **變數**：像是一個個單獨的「抽屜」。
        * **物件**：則是一個擁有多個抽屜的「檔案櫃」，每個抽屜都有自己的標籤（屬性名稱）和內容（屬性值）。

---

* **2. 物件的組成：屬性與方法**
    * 一個物件主要由兩種成員組成：
    * **屬性 (Property)**：用來描述物件特徵的「資料」，通常是名詞或形容詞。
        * `age: 18` (`age` 是屬性名稱，`18` 是屬性值)
        * `name: "小明"`
    * **方法 (Method)**：物件可以執行的「功能」，本質上就是一個被放在物件內的函式，通常是動詞。
        * `talk: function() { ... }` (`talk` 是方法名稱)

---

* **3. 建立物件：`{}` 物件字面值 (推薦)**
    * 這是建立物件最簡單、直接且最常用的方式。
    * **語法**：
        ```javascript
        let obj = {
            成員名稱1: 資料1,
            成員名稱2: 資料2,
            方法名稱: function() { ... }
        };
        ```
    > [!TIP]
    > **物件字面值 vs. JSON**
    >
    > `{}` 這種語法在 JavaScript 中稱為「**物件字面值 (Object Literal)**」。它的格式與 **JSON (JavaScript Object Notation)** 幾乎一模一樣，但兩者用途不同：
    > * **物件字面值**：用來在 JavaScript 程式中「建立物件」。
    > * **JSON**：是一種純文字格式，專門用來在不同系統之間「交換資料」。

    * **程式碼範例**：
        ```javascript
        // 建立一個空物件
        let obj1 = {}; 

        // 建立一個有初始成員的物件
        let obj2 = {
            x: 3,
            y: 4,
            show: function() {
                console.log(this.x, this.y);
            }
        };
        ```

* **4. 存取與操作物件成員**
    * 我們可以透過「點 `.`」來存取、新增或修改物件的成員。
        ```javascript
        // 建立空物件
        let obj = {};

        // 新增/設定成員
        obj.x = 3;
        obj.y = 4;
        obj.show = function() {
            console.log("Hello");
        };

        // 讀取/使用成員
        console.log(obj); // 印出整個物件
        console.log(obj.x + obj.y); // 印出 7
        obj.show(); // 呼叫物件的方法，印出 Hello
        ```
        ![image](https://hackmd.io/_uploads/SybwIKM8ee.png =40%x)


---

* **5. `this` 的魔力：讓物件與自己對話**
    * 在物件的**方法 (Method)** 中，`this` 這個關鍵字，就代表了「**這個物件本身**」。
    * **比喻**：當 `man` 這個物件在執行 `talk` 方法時，方法裡的 `this.name` 就像是 `man` 在說「**我自己的名字**」，`this.age` 就像是在說「**我自己的年齡**」。`this` 提供了方法一個存取自己家（物件）內部其他成員的途徑。
    * **程式碼範例**：
        ```javascript
        let obj = {
            x: 3,
            y: 4,
            show: function() {
                // 這裡的 this 就等於 obj 這個物件
                // 所以 this.x 就等於 obj.x
                console.log(this.x, this.y);
            }
        };

        obj.show(); // 印出 3 4
        ```

---

* **6. 綜合練習**

    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Javascript 物件基礎</title>
    </head>
    <body>
        <script>
            // === 練習 1：使用 new Object() 建立物件 (較舊的寫法) ===
            console.log("--- 方法一：new Object() ---");
            // 1. 建立一個空白物件
            let man = new Object();
            
            // 2. 逐一新增屬性與方法
            man.age = 18;
            man.name = "666";
            man.talk = function () {
                // 3. 在方法中，使用 this 代表 man 這個物件本身
                console.log("Hello 我是", this.name, "，年齡", this.age);
            };

            // 4. 使用物件
            console.log("man 物件的內容:", man);
            console.log("man 是否大於 20 歲:", man.age > 20); // 印出 false
            man.talk(); // 呼叫 man 物件的 talk 方法

            console.log("--- 分隔線 ---");

            // === 練習 2：使用物件字面值 {} 建立物件 (現代推薦的寫法) ===
            console.log("--- 方法二：物件字面值 {} ---");
            // 1. 在建立時就同時定義好所有成員
            let man2 = {
                age: 15,
                name: "小芬",
                talk: function () {
                    // 2. 這裡的 this 代表 man2 這個物件本身
                    console.log("Hello 我是", this.name, "，年齡", this.age);
                }
            };

            // 3. 使用物件
            console.log("man2 物件的內容:", man2);
            console.log("man2 是否大於 20 歲:", man2.age > 20); // 印出 false
            man2.talk(); // 呼叫 man2 物件的 talk 方法
        </script>
    </body>
    </html>
    ```
    
    :::spoiler 成果展示
    ![image](https://hackmd.io/_uploads/S1MRcKzUxx.png)
    :::
    
