# if 數值區間 + 邏輯運算子 & 物件與陣列設計 >若有任何疑問請至 Discord「作業討論」頻道討論 ## 本章節我們要學什麼? ### if 數值區間 + 邏輯運算子(1 ~ 5 題) 學習[條件判斷](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/if...else),並且了解[邏輯運算子](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Expressions_and_Operators),透過生活中常見情境來練習邏輯能力。 ### 物件與陣列設計(6 ~ 10 題) 前面幾週練習了字串與數字,這次要來學習「物件與陣列」。在 Javascript 中,**陣列是一種具有特殊方法與屬性的物件**,可以把陣列視作「特別用於存儲有序列狀的資料」的資料型態。 * 物件:一個物體,由鍵與值構成與描述。 * 陣列:一個清單,由元素和索引構成。 參考文件:[MDN陣列](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array)、[MDN物件](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/) ![](https://i.imgur.com/XCkhtuf.jpg) ![](https://i.imgur.com/OhCiUsE.jpg) 部分題目下方附有 keywords,表示該題目運用到課堂外的語法或技巧,同學可依照 keywords 搜尋了解概念。 ## 題目一:多重條件 一週有七天,請製作一個函式可輸入不同的星期日數,並回傳當天的心情小語,如下例: ``` =JavaScript // input 輸入 myThought(1) myThought(7) myThought(8) // output 輸出 "星期一:穿新衣。" "星期日:來考試。" "一周只有七天,輸入錯囉" ``` **(心情小語內容可自訂、必須使用 [Switch](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/switch) 語法來達成。)** ## 題目二:溫標轉換 目前常見的溫度標示有攝氏(°C)與華氏(°F),請撰寫兩個函式可以轉換彼此四捨五入至小數第一位,如下範例。 * 攝氏轉華氏: (10°C x 9/5) + 32 = 50°F * 華氏轉攝氏: (10°F − 32) × 5/9 = -12.2°C ``` =JavaScript // input 輸入 CtoF(10) FtoC(10) // output 輸出 50 -12.2 ``` ✨keywords:Math.round() ## 題目三:計算球體體積 請製作一個球體積計算函式,參數為半徑,回傳計算後四捨五入取至第一位小數的結果。 球體積 = 4 / 3 x π x 球半徑³ ``` =JavaScript // input 輸入 sphereVolume(1) sphereVolume(10) sphereVolume(20) // output 輸出 4.2 4188.8 33510.3 ``` 可參考:[球體積計算機](https://www.google.com/search?client=firefox-b-d&q=sphereVolume+calc) ✨keywords:Math.PI ## 題目四:BMI 計算 BMI 稱為身體質量指數(Body Mass Index,縮寫為BMI),是目前美國疾病管制局及世界衛生組織所認可,利用身高為基礎來測量體重是否符合標準。請套用以下公式製作一個 BMI 計算函式。 <div style="text-align: center; padding: 4rem"> BMI = 體重(公斤) / 身高的平方(公尺) </div> ![BMI範圍表格](https://i.imgur.com/Ca8hB0Z.png) ``` =JavaScript // input 輸入 bmi(cm,kg) bmi(178,20) bmi(178,65) bmi(178,77) bmi(178,89) bmi(178,100) bmi(178,200) // BMI(身高,體重) // output 輸出 "體重過輕" "正常範圍" "異常範圍" "異常範圍" "異常範圍" "異常範圍" ``` 延伸思考:可將過重、輕度肥胖、中度肥胖、重度肥胖、腰圍功能判斷也完成。 ## 題目五:FizzBuzz FizzBuzz 是一個簡單的小遊戲,給定一串從 1 到 100 的數字: * 如果是 3 的倍數,就印出 “Fizz” * 如果是 5 的倍數,就印出 “Buzz” * 如果同時是 3 和 5 的倍數,就印出 “FizzBuzz” * 將結果回傳為一個陣列。 ``` =JavaScript // Todo 待完成 function fizzBuzz100(){ let result = [] let count = 1 while (count <= 100) { // // 在此的程式將會被執行 100 次 // 請撰寫判斷將 FizzBuzz 與數字放入 result 陣列之中 // count ++ } return result } // input 輸入 fizzBuzz100() // output 輸出 ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"......後續省略] ``` ## 題目六:創建陣列與物件 請分別創建一個陣列與物件用於存儲以下資訊並在瀏覽器的 Console 中打印出來: * **待買備忘錄 (用陣列表示)** * 牛奶 * 酪梨 * 咖啡粉 * 蘋果麵包 * **用戶的資訊 (用物件表示)** * 年紀: 20 * 名稱: 小明 * 生理性別: 男 * 興趣: 前端開發、讀書、跑步 * 喜歡的食物: 滷肉飯 * 吃素: 否 ``` =JavaScrip // 附註:同學可嘗試放入任何自訂內容,著重在練習語法操作。 // Todo 待修改 const toBuyList = [] const userInfo = {} console.log(toBuyList) console.log(userInfo) // Output 輸出 ["牛奶", "酪梨", "咖啡粉", "蘋果麵包"] { age: 20, name: "小明", sex: "男", hobby: ["前端開發", "讀書", "跑步"], favoriteFood: "滷肉飯", isVegetarian: false } ``` ## 題目七:複製陣列或物件(淺拷貝) :::info 如果還沒有概念如何操作,可參考以下文檔。 * [ES6 展開語法:Spread syntax (...)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax) * [物件複製:Object.assign()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) ::: JavaScript 在創建變數、賦值後除了基本型態外都是以傳址(call by refence)來去記載內容位置,雖然可以節省記憶體使用但也會造成「改 A 更動到 B」的問題。 參考資料:[Pass by value, or Pass by reference?](https://ithelp.ithome.com.tw/articles/10209104) 接續第六題,請複製一份相同的內容(使用淺拷貝的方式)到全新的陣列、物件之中。 ``` =JavaScrip // Todo 待修改 const newToBuyList = [] const newUserInfo = {} console.log(newToBuyList) console.log(newUserInfo) // Output 輸出 ["牛奶", "酪梨", "咖啡粉", "蘋果麵包"] { age: 20, name: "小明", sex: "男", hobby: ["前端開發", "讀書", "健身"], favoriteFood: "滷肉飯", isVegetarian: false } ``` ✨keywords:Pass by value、Pass by reference ## 題目八:修改陣列與物件(增、刪、改) :::info 增、刪、改陣列或物件的方式有很多種,如還沒有概念如何操作可以參考以下文章。 * [(Ray) 關於 JavaScript 陣列 20 種操作的方法](https://israynotarray.com/javascript/20190421/1216566123/) * [(卡斯伯) JavaScript 陣列處理方法](https://www.casper.tw/javascript/2017/06/29/es6-native-array/) ::: 接續第七題,在淺複製完 ToBuyList、UserInfo 後對陣列與物件做以下的更動,並打印出來。 **陣列:** * 刪除陣列中的 "咖啡粉" * 新增 "布丁" 為陣列的首筆資料 * 刪除陣列中的最後一筆資料("蘋果麵包") **物件:** * 將小明的年齡 +1 * 將小明是否吃素改為 true * 新增 key 為 "hasDriverLiscense",value 為 true * 刪除 key "favoriteFood" ``` =JavaScrip // Todo 待編輯 // // 請在此對新物件與陣列做更動。 // console.log(newToBuyList) console.log(newUserInfo) // Output 輸出 ["布丁", "牛奶", "酪梨"] { age: 21, name: "小明", sex: "男", hobby: ["前端開發", "讀書", "健身"], isVegetarian: true hasDriverLiscense: true } ``` ✨keywords:unshift()、pop()、delete object.property ## 題目九:複製陣列或物件(深拷貝) :::info 關鍵字與參考資料: * [MDN Json.prase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) * [JSON.stringify()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) * Array Deep Clone ::: ``` =JavaScrip // Input 輸入 const nestedNumbers = [[1], [2]]; const numbersCopy = [...nestedNumbers]; numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // Output 輸出 // 兩個變數都被更改了,因為他們共享相同的記憶體位址來存儲資料。 [[1, 300], [2]] [[1, 300], [2]] ``` **(請先參考以上代碼了解問題點)** 在大多情況下使用淺層拷貝就足矣,但當情況稍微複雜一點(嵌套的陣列或物件),在第二層還是會出現共享記憶體位址來存儲資料的問題,造成:「更動 A 陣列也跟著改動到 B 陣列」的問題。 請創造 nestedNumbers 並深層複製出 deepCloneNestedNumbers,使其各自有獨立的記憶體位置存放資料。 ``` =JavaScrip // Todo 待編輯 const nestedNumbers = [[1], [2]]; const deepCloneNestedNumbers = [] deepCloneNestedNumbers[0].push(300) console.log(nestedNumbers, deepCloneNestedNumbers) // Output 輸出 [[1], [2]] [[1, 300], [2]] ``` ## 題目十:月有陰晴圓缺🌚🌝 :::success 先喘一口氣,接著挑戰如何使用原生方法處理陣列。通常會建議同學基本了解以下最常用的方法,就足夠應付大多場合: * [為什麼要學陣列資料處理?](https://courses.hexschool.com/courses/202011131111/lectures/61649425) * [forEach](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) * [map](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Map) * [filter](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) * [reduce](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) ::: 請製作一個函式可以回傳出月亮一周期的過程,並且在"滿月 🌕"時加上"月餅 🥮"字串。 ``` =JavaScrip // Todo 待編輯 function moonCakeTime(planetPhase) { } const moonPhase = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"] console.log(moonCakeTime(moonPhase)) // Output 輸出 ["🌑","🌒","🌓","🌔","🌕 + 🥮","🌖","🌗","🌘"] ``` <!-- 參考答案: https://codepen.io/fhljksmg-the-styleful/pen/KwdjGrQ?editors=0012 答案僅供參考, 答案會使用各種方式書寫(非最佳化)並加上部分解說, 適合初學者還不太會解題或者是該題卡住的同學。 -->