# 🏅 Day 6 - 列舉型別(Enum) 列舉(Enum)型別用於取值,在 C# / C / JAVA 常見到它的身影,而本身 JavaScript 是沒此語言特性的。 **列舉適合被限制在一定範圍內的場景**,例如一週只能有七天,紅綠燈有紅、綠、黃的狀態。 ```tsx= enum Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } // 使用列舉 console.log(Weekday.Monday); // 印出 1 ``` 為何顯示為 1 呢?這是因為列舉成員被初始化時,會從 0 開始按順序賦予遞增的數值,而且還會實現從列舉的值到其名稱的反向映射。 ```tsx= enum Weekday { Sunday, // 賦值為 0 Monday, // 賦值為 1 Tuesday, // 賦值為 2 Wednesday, // 賦值為 3 Thursday, // 賦值為 4 Friday, // 賦值為 5 Saturday // 賦值為 6 } // 範例一:使用數字來取得對應的列舉名 let dayName = Weekday[2]; // dayName 值為 "Tuesday" // 範例二,顯示今天禮拜幾 let today = Weekday.Monday; // today 值為 1 ``` 這段輸出 JavaScript 的話,會變成如下,好讓 JavaScript 也擁有列舉功能 ```tsx= "use strict"; var Weekday; (function (Weekday) { Weekday[Weekday["Sunday"] = 0] = "Sunday"; Weekday[Weekday["Monday"] = 1] = "Monday"; Weekday[Weekday["Tuesday"] = 2] = "Tuesday"; Weekday[Weekday["Wednesday"] = 3] = "Wednesday"; Weekday[Weekday["Thursday"] = 4] = "Thursday"; Weekday[Weekday["Friday"] = 5] = "Friday"; Weekday[Weekday["Saturday"] = 6] = "Saturday"; // 賦值為 6 })(Weekday || (Weekday = {})); // 範例一:使用數字來取得對應的列舉名 let dayName = Weekday[2]; // dayName 值為 "Tuesday" // 範例二,顯示今天禮拜幾 let today = Weekday.Monday; // today 值為 1 ``` ## enum 手動賦值 除此之外 enum 也可以賦值為其它型別,方便開發者運用 ```tsx= enum Weekday { Sunday = "Sun", Monday = "Mon", Tuesday = "Tue", Wednesday = "Wed", Thursday = "Thu", Friday = "Fri", Saturday = "Sat" } // 範例一:使用列舉名來取得對應的字串簡寫 let dayName = Weekday.Tuesday; // dayName 值為 "Tue" // 範例二:顯示今天星期幾(以簡寫形式) let today = Weekday.Monday; // today 值為 "Mon" ``` ## 範例:紅綠燈 像是紅綠燈它就是屬於狀態限制在一定範圍,也就是只有紅綠黃色,就相當適合使用 enum 來定義。 ### 沒使用 enum 的話 在我們寫程式時,通常會用數字來代表不同的狀態。在技術上雖然可行,缺點就是可讀性很差,當其它同事接手你的程式碼時,需要知道每個數字代表的意思,就變得不好理解。 也不要說同事,可能過一週,你自己也看不懂這些數字的意涵了,如下程式碼範例: ```tsx= // 定義紅綠燈狀態的數字 const RED = 0; const YELLOW = 1; const GREEN = 2; // 當前紅綠燈狀態 let currentLight = RED; // 檢查紅綠燈狀態 function checkTrafficLight(status: number) { if (status === RED) { console.log("紅燈,請停止!"); } else if (status === YELLOW) { console.log("黃燈,請注意!"); } else if (status === GREEN) { console.log("綠燈,可以行駛!"); } else { console.log("未知燈號!"); } } // 檢查當前燈號 checkTrafficLight(currentLight); ``` ### 有用 enum 範例 編號完全消失不見,另外藉由參數上的型別註釋,可讀性與維護性也大為提升: ```tsx= enum TrafficLight { Red, // 紅燈 Yellow, // 黃燈 Green // 綠燈 } // 當前紅綠燈狀態 let currentLight = TrafficLight.Red; // 檢查紅綠燈狀態 function checkTrafficLight(status: TrafficLight) { switch (status) { case TrafficLight.Red: console.log("紅燈,請停止!"); break; case TrafficLight.Yellow: console.log("黃燈,請注意!"); break; case TrafficLight.Green: console.log("綠燈,可以行駛!"); break; default: console.log("未知燈號!"); } } // 檢查當前燈號 checkTrafficLight(currentLight); ``` ## 待辦事項範例程式碼 ```tsx= enum TodoStatus { Pending, // 待辦事項尚未開始 InProgress, // 待辦事項正在進行中 Completed, // 待辦事項已完成 Cancelled // 待辦事項被取消 } // 待辦事項陣列 let todos = []; // 新增待辦事項的函數 function addTodoItem(name: string) { const newTodo = { name: name, status: TodoStatus.Pending // 新增的待辦事項默認狀態為 "Pending" }; todos.push(newTodo); console.log(`新增待辦事項: "${name}"`); } // 範例:新增一個待辦事項 addTodoItem("完成 TypeScript 專案"); // 顯示目前所有待辦事項 console.log(todos); ``` ## 列舉、元組、陣列 蠻多開發者比較難判斷何時用這三種資料結構,以下摘要分享: | 特性/用途 | 列舉 (Enum) | 元組 (Tuple) | 陣列 (Array) | | --- | --- | --- | --- | | 用途定義 | 表示一組相關的資料集合,如狀態或選項。 | 儲存固定數量、固定順序的多種型別的值。 | 儲存多個相同型別的值。 | | 索引方式 | 通過名稱或數值索引。 | 通過位置索引。 | 通過位置索引。 | | 語義清晰性 | 高(每個值都有明確的名稱)。 | 中(位置重要,但型別可以變)。 | 低(因會儲存多資料內容)。 | | 例子 | enum Color { Red, Green, Blue } | let point: [number, number] = [7, 5]; | let numbers: number[] = [1, 2, 3]; | | 應用場景 | 固定的選項(如天數、狀態)。 | 當需要固定組合的不同型別值時(如座標、excel 欄)。 | 儲存一系列相同型別的元素(例如數據列表)。 | ### 使用情境: 1. 如果你需要表示一組固定的選項,如天數、方向、狀態,可以使用 **列舉** **`enum`**。 2. 假使你需要存儲固定長度的多種類型的數據(如座標、excel 欄),可以使用**元組**。 3. 需要儲存大量相同型別數據的情況,如數據列表,可以使用**陣列**。 ## 題目 請觀察以下情境,並推斷他適合哪種型別格式: 1. 情境:你需要儲存不同的使用者角色,如「管理員」、「使用者」和「訪客」。這些角色是固定的且有特定的名稱。 A. 列舉 (Enum) B. 元組 (Tuple) C. 陣列 (Array) 2. 情境:你正在開發一個函式,需要回傳一個包含經度和緯度的地理座標。 A. 列舉 (Enum) B. 元組 (Tuple) C. 陣列 (Array) 3. 情境:你需要一個儲存全台灣各家庭的數據資料,例如每個家庭的總年收入。 A. 列舉 (Enum) B. 元組 (Tuple) C. 陣列 (Array) 4. 情境:你需要表示一週的七天,每天都有一個特定的名稱。 A. 列舉 (Enum) B. 元組 (Tuple) C. 陣列 (Array) 5. 情境:你需要追蹤一個電子商務網站上的產品類別,這些類別已經固定,不會隨時間而更改。 A. 列舉 (Enum) B. 元組 (Tuple) C. 陣列 (Array) ## 開發題 ### **題目標題: 設計一個訂單處理系統** ### 情境描述: 你正在開發一個電子商務系統,需要處理不同階段的訂單。為了更好地追蹤和管理訂單,你決定使用 TypeScript 的 **`enum`** 來表示訂單的各個處理階段。 ### 任務: 1. 定義一個名為 **`OrderStatus`** 的 **`enum`**,其中包括以下狀態:待處理(Pending)、運送中(Shipping)、已送達(Delivered)、已取消(Cancelled)。 2. 建立一個函式,名稱為`changeOrderStatus`,藉此更新訂單狀態 - 參數:訂單 ID (**`orderId`**) 和新的訂單狀態 (**`newStatus`**)。 - 回傳:無(僅在控制台印出更新訊息)。 ### 有欠缺的程式碼: ```tsx enum OrderStatus // 更新訂單狀態 function changeOrderStatus(orderId, newStatus) { console.log(`訂單 ${orderId} 的狀態已更新為:${newStatus}`); } // 範例使用 let orderId = 123; // 假設的訂單 ID changeOrderStatus(orderId,訂單狀態); ``` <!-- 解答: 單選題目:ABCAA 開發題:https://codepen.io/hexschool/pen/NWJbwve?editors=1011 ``` --> ## 回報流程 將答案寫在 CodePen,並貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) 回報區 --- | Discord | CodePen / 答案 | |:-------------:|:----------------------------------------------------------------:| |洧杰|[Codepen](https://codepen.io/hexschool/pen/NWJbwve?editors=1011)| |苡安|[Codepen](https://codepen.io/yi-an-yang/pen/vYPgNmZ)| |Jack|[Codepen](https://codepen.io/lj787448952/pen/abMpvyv)| |ZS|[Codepen](https://codepen.io/irishuang/pen/poYRjam)| |HsienLu|[Codepen](https://codepen.io/Hsienlu/pen/GRerpBx?editors=1111)| |BonnieChan|[Codepen](https://codepen.io/Bonnie-chan-the-bold/pen/eYXgprY?editors=1111)| |hannahTW|[Codepen](https://codepen.io/hangineer/pen/LYaxprW?editors=1011)| |YC|[HackMD](https://hackmd.io/SKoJd3EsTlitnjzCx4Rarg?view)| |銀光菇|[CodePen](https://codepen.io/genesynthesis/pen/ExMZVmj)| |皓皓|[HackMD](https://hackmd.io/@cutecat8110/H1ZNTzMKa)| |hiYifang|[HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/SkhePfMKa)| |LinaChen|[HackMD](https://codepen.io/LinaChen/pen/LYaxNQw)| |m_m|[CodePen](https://codepen.io/minnn7716/pen/LYaxNvE)| |rikku1756|[CodePen](https://codepen.io/rikkubook/pen/LYaxNwV?editors=1011)| |黃士桓|[codePen](https://codepen.io/shr-huan-huang/pen/KKEaMyE)| |Judy ☻|[Codepen](https://codepen.io/hsiaohan/pen/vYPgyNo?editors=1011)| |Starr|[CodePen](https://codepen.io/StarrZhong/pen/qBvRqxG)| |展誠|[Codepen](https://codepen.io/hedgehogkucc/pen/QWoddmz?editors=1012)| |Henry_Wu|[Codepen](https://codepen.io/hekman1122/pen/xxBRbMQ?editors=1011)| |Bryan Chu|[CodePen](https://codepen.io/bryanchu10/pen/poYRPaa)| |Shaokang|[CodePen](https://codepen.io/tony-hsueh/pen/KKEgBKE?editors=1111)| |Lisa|[CodePen](https://codepen.io/lisaha/pen/NWJdgKy)| |wendy_.li|[HACKMD](https://hackmd.io/PcmFgqZwRd-4Ep3-LgK5_Q#TypeScript-%E9%99%A3%E5%88%97)| |deedee1215|[CodePen](https://codepen.io/diddy032/pen/WNmRjVM)| |Zuo|[CodePen](https://codepen.io/linchinhsuan/pen/abMpyOJ)| |Yao|[CodePen](https://codepen.io/AlbertoLL/pen/oNVBepd)| |77_0411|[CodePen](https://codepen.io/chung-chi/pen/BabpdjM?editors=1111)| |jasperlu005|[Codepen](https://codepen.io/uzzakuyr-the-reactor/pen/WNmRELr?editors=1111)| |Alyce|[Codepen](https://codepen.io/alycehwy/pen/abMpLxr?editors=0011)| |Mi|[CodePen](https://codepen.io/Mi-Jou-Hsieh/pen/NWJdapd?editors=1100)| |yunhung|[CodePen](https://codepen.io/ahung888/pen/XWGpVrd)| |連小艾|[Codepen](https://codepen.io/bolaslien/pen/mdoRKqJ?editors=1012)| JC|[Codepen](https://codepen.io/jcsamoyed/pen/wvOgYNd?editors=0012) |Yang|[Codepen](https://codepen.io/Yang-J/pen/poYRGLd)| |薏慈|[Codepen](https://codepen.io/its_wang/pen/MWxJdWm?editors=1010)| |shan13|[Codepen](https://codepen.io/yishan13-tsai/pen/gOEgVWQ)| |神奇海螺|[CodePen](https://codepen.io/ksz54213/pen/JjzWjyd)| |Kai|[CodePen](https://codepen.io/kaiyuncheng-the-styleful/pen/mdoWJmb?editors=0012)| |NiuNiu|[CodePen](https://codepen.io/Dawson-the-bold/pen/WNmRWqr?editors=0010)| |Amberhh|[codepen](https://codepen.io/Amberhh/pen/QWopNRO?editors=1011)| |clairechang|[Notion](https://claire-chang.notion.site/Day-6-Enum-34d445a092114876bdf154e1f98707b1)| |erwin阿瀚|[CodePen](https://codepen.io/yohey03518/pen/JjzWKdg?editors=1010) |Otis|[CodePen](https://codepen.io/humming74/pen/gOEmxrK?editors=1011) | |翰毅|[CodePen](https://codepen.io/yzuigtdw-the-animator/pen/wvOJdNg?editors=1111)| |fanshu0303|[CodePen](https://codepen.io/JuiHsuanLee0303/pen/xxBqoXv)| |wei|[CodePen](https://codepen.io/jweeei/pen/ZEPedOM?editors=1011)| |Teddy|[CodePen](https://codepen.io/TaideLi/pen/KKEmMWo)| |精靈|[CodePen](https://codepen.io/justafairy/pen/VwRWaWB)| |小米|[CodePen](https://codepen.io/joanne-wei/pen/rNRwpJB?editors=0012)| |ethan1331|[CodePen](https://codepen.io/EthanTsai/pen/qBvjQLz) | |leave3310|[CodePen](https://codepen.io/leave3310-the-looper/pen/VwRWJMJ?editors=0011) | |zoe|[Codepen](https://codepen.io/Zoechiueh/pen/ZEPXPYO?editors=0011)| |亞當|[Codepen](https://codepen.io/Adam-Hsu/pen/OJqOyzK?editors=0011)| |Snorlax|[HackMD](https://hackmd.io/@snorlaxpock/SyjwMhiFa)| |Nick Lin|[HackMD](https://codepen.io/NickLinP/pen/vYPpYVQ)| |Yoshi|[CodePen](https://codepen.io/yoshiyyc/pen/XWGzPoo)| |Rochel|[Codepen](https://codepen.io/rochelwang1205/pen/vYPpoOQ)| |Eileen|[Codepen](https://codepen.io/Eileen-io/pen/GReQprx)| |狸貓|[Codepen](https://codepen.io/tanuki320/pen/eYXrMaO?editors=1011)| |阿鬥鬥|[HackMD](https://hackmd.io/yiFczUf9RrO4jceg5ZEdhQ?view#Day-6---%E5%88%97%E8%88%89%E5%9E%8B%E5%88%A5%EF%BC%88Enum%EF%BC%89)| |aki|[codepen](https://codepen.io/aki168/pen/abMKOZE)| |Tori|[HackMD](https://hackmd.io/OAdkiOH-S_WkD-LF6IONVA?view)| puffy| [Codepen](https://codepen.io/TernMayDay/pen/OJqqQKg?editors=0011) | 我是泇吟 | [CodePen](https://codepen.io/kljuqbxs/pen/bGPyddE) |