# 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 不更新