# 📚 前端網頁開發基礎(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) :::