# 0322 ## 遞迴 (**Recursive**) 遞迴主要是藉由函數可以呼叫自己的特性並搭配邊界條件(終止條件)來達成 如果沒有終止條件則會造成 stack overflow, 但都可以用迴圈寫 ### 例子 : 斐波那契 (費氏) 數列 ```jsx /*費氏數列的條件 1.F0 = 0 2.F1 = 1 3.Fn = Fn-1 + Fn-2 (n>=2)*/ function fib(x){ if(x < 2){ return x } return fib(n - 1) + fib (n - 2) } ``` ## Switch case 不會做型別上的轉換比較, 如: ```jsx switch (1) { case '1': //此行會跳過 break //若不加 break 則會繼續往下執行直到結束或遇到 break case 2 : ... } ``` ## async / await await 必須在 async 的 function 裡面,此為非同步的寫法。 正常程式為一行一行執行,但此寫法會等待資料後再執行 如例子,會在畫面先呈現 “此行會先行” 而不是抓回來的 title,當 title 抓回來後,便會在執行並出現在主控台。 ```jsx const api = ' api網址 ' async function getPost() { const response = await fetch(api) const posts = await response.json() posts.forEach((post) => { console.log(post.title) }) } getPost() console.log('此行會先行') ``` ## For in / For of for in 用在物件上, 可得到 key值 ```jsx const obj = {name: "kk", sex: "male", height: 165, weight: 56} for (let variable in obj){ console.log(variable) } // name, sex, height, weight ``` for of 用在可迭代的物件上 (如 : 陣列) ```jsx const const arr = [1, 2, 3, 4, 5, 6] for (let n of arr){ console.log(n) } // 1, 2, 3, 4, 5, 6 ``` ```jsx const obj = {name: "kk", sex: "male", height: 165, weight: 56} for (let x of Object.values(obj)){ console.log(x) } // kk, male, 165, 56 ; Object.values(obj) 為回傳陣列, 就可用 of 迭代 ``` 使用時, for 內的變數需要宣告, 不然函式外依就可以使用, 會造成污染 通常可迭代的物件是有順序性, 物件(entries, keys, values) 是沒有順序概念的 亦可加入解構, 如: ```jsx const obj = {name: "kk", sex: "male", height: 165, weight: 56} for (const [ _ , v] of object.entries(obj)){ console.log(v) } // kk, male, 165,56 ``` ## Promise → Loop event 補充 因 promise 抓取資料要時間, 在 Web api 處等待抓取, 資料回來時會直接進到 Queue 而 Queue 有另一條可快速通過, 若 stack 清空, 會先以此條快速通道為主, 其次才是普通的 queue fetch 有特權, 故抓取的資料會優先處理 (快速的 queue) ## NEW (建構子函數 用於建立物件, 其步驟: 1. 編寫建構子函數以完成物件類型的定義。 2. 使用 new 建立物件的實體。 在建構函式內, 不用加入 return, 若是 return 字串會忽略, 但若是陣列或物件, 則會蓋過原本的內容, 絕對不要回傳, 以免麻煩 ### 寫法 ```jsx class duck { eat(){ console.log('yummy!!') } } // 與下方效果相同 function duck(){ eat(){ console.log('yummy!!') } } const d1 = new duck() ``` ## **[淺拷貝 (shallow copy) 和深拷貝 (deep copy)](https://www.explainthis.io/zh-hant/swe/shallow-copy-and-deep-copy)** 淺拷貝值所指的地方是一樣的, 深拷貝則是值所存的地方不同 複製方式詳見文章 ```jsx // lodash 的淺拷貝 clone var objects = [{ a: 1 }, { b: 2 }]; var shallow = _.clone(objects); console.log(objects === shallow); // false console.log(shallow[0] === objects[0]); // true // lodash 的深拷貝 cloneDeep var objects = [{ a: 1 }, { b: 2 }]; var deep = _.cloneDeep(objects); console.log(objects === deep); // false console.log(deep[0] === objects[0]); // false ``` ## LocalStorage 若在網頁上要儲存使用者資料, 存資料有兩處 : 1. 伺服器端 2. 本地端記憶體 (LocalStorage) 而此為瀏覽器所提供的方法, JavaScript 無此功能, 此功能僅有兩個屬性, localStorage.setItem (存), localStorage.getItem (取) 因存取會自動以字串的模式進行, 若由 JS 自行轉型別, 會使 object 轉成 { object object } 使資料失真, 故會以 JSON.stringity() 將該物件以 JSON 方式轉為字串存入, 取出時以 JSON.parse() 轉回, 便可供後續使用 ## OOP (生成函數的語法糖 ```jsx class heroCreator { constructor(name){ this.name = name } } //以上寫法同 function heroCreator(name){ this.name = name } const h1 = new heroCreator('kk') //應用在個別上面兩個後所產生的效果一樣 ``` ## 封裝 ESM = ES module // ES 為 ECMAScript 縮寫 為 物件導向 的特色之一, 用途為將某 JS 檔案中函數或物件……等等, 傳出至另一個 JS 檔案中使用, 可延用該功能, 並不損及原檔案 ### 啟用 1. 在 HTML 中的 \<script> 標籤內加入 type = ‘module’ 來啟用 module 功能 2. 在要輸出模組的 .js 檔案中, 選擇要輸出的東西 (物件、函式、變數……等), 輸出法如下: 1. 在輸出的檔案中任一處寫, export {要輸出的東西名1, 函數名2, …} ; 此為 named export ```jsx function test(){} export { test } ``` 2. 在輸出的函式宣告前面加入 export ```jsx export function test(){} ``` 3. 在最下方用 export default 函式名 輸出 ; 此為 default export 但此方法只能輸出一個東西, 通常為表達整個模組想做的事 ```jsx function test(){} export default test ``` named export 跟 default export 可混用, 但 default 要寫在前面再加入大括號, 限同一檔案輸出 ```jsx export default test { other } ``` 3. 輸入的 .js 檔案要寫入接收, 依輸出的方式不同, 輸入方式也有差異 1. named export ```jsx import { 要輸入函數名 } from “路徑/匯入函數的檔案名” // 若輸入變數名稱重複可改名 {輸入名 as 新名字} ``` 2. default export ```jsx import 名字可隨意取 from “輸出來源” //如 : import someName from “./app.js” ``` 用模組的狀況下, 嚴格模式是打開的 ### 延伸 → 實務上安裝套件 使用 npm 安裝模組 ## [語意化版本管理](https://semver.org/lang/zh-TW/) ### 組成 版本號由三個部分組成, 如 : 2 . 6 . 8 - 第一個數 “2” , 為 major, 視為版本大改, 先以不相容原版本為前提 - 第二個數 ”6” , 為 minor, 通常為加了向下相容的新功能 - 最後一個 “8” , 為 patch, 為向下相容的問題修正 ### 符號 在套件上的版本號若有符號則代表, 更新時所需注意事項 - ^ (caret):則有出新的minor 會直接升到該版本, 但major 版本不能更新 - ~ (tilde):頂多予許 patch 跟到最新, 最好就這樣, 因為資安更新通常也patch - > :一有更新則完全更新, 不管版號 如:^1.6.8 : 更新至minor, 若 major 升級改版則不升級、~1.6.8 為patch 更新即可, minor 不更新