---
# System prepended metadata

title: ＪＳ影片筆記
tags: [五倍, JS]

---

此為龍哥影片內的筆記, 請由左側選擇想看的部分做查詢
此筆記不含實作練習部分, 該部份請自行看影片與練習

# 名詞

EMCA : European Computer Manufacturers Association 歐洲電腦製造協會

TC39 : Technical commitee 39 (EMCA 底下的一個委員會)
此委員會有提出 ECMA-262 (一種標準化規格)

EMCAScript : 根據 ECMA-262 規範所制定的程式語言規格

ES6 : EMCAScript 6

# 前置基礎

JS 主要寫在

- 瀏覽器的 console (主控台)
- 網頁
    - 寫在 <script> 標籤裡或外部檔案
    - 放在 <head> 標籤裡
    - 放在 <body> 標籤裡
- 直接寫在某些 html 的 dom 元素上

註解

- 單行用 /
- 多行用 /* */

分號

盡量不要自動安插分號，電腦會猜錯

等號

一個等號 : 在設置變數中為 指定 (assing) 的意思

# **變數、常數、資料型態**

## 宣告變數

命名規則 : 

- 可用英文或數字，但開頭第一個字母不可以是數字
- 不可使用保留字
    - [保留字](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords)
        
        
        | break | default | for | return | var |
        | --- | --- | --- | --- | --- |
        | case | delete | function | super | void |
        | catch | do | if | switch | while |
        | class | else | import | this | with |
        | const | export | in | throw | yield |
        | continue | extends | instanceof | try |  |
        | debugger | finally | new | typeof |  |
- 注意大小寫有區別
- 望文生義
- 慣例 : 駝峰式命名法

變數 (variable) : 像是容器來指示出”值 (value)”，而值本身可以是 數字、文字、布林值……等。

用 const 宣告常數 : 常數不是不能改，而是不能「重新指定 (re-assign)」

### 未定義與沒有定義

未定義 (undefined) : 存在，但沒有定義

沒有定義 (not define) : 連存在都不存在

### 變數提昇 (Variable Hoisting)

未宣告變數，但後面有宣告並賦予值時。前面未宣告的變數會先以未定義 (undefined) 存在，在後面宣告時才有值。~~( 使用 var 宣告時，用 let 宣告一樣會出現錯誤，但 let 還是有變數提昇的狀況 )~~
(因 JS 是屬兩段執行，第一次會先掃過變數，第二次才是正式執行賦值 (簡單解釋版))

## let, const, var 如何選擇

- 能 const 就用 const, 不能用 const 就用 let
- var 也可以用, 但它的範圍 (Scope) 比較大
- 千萬不要沒宣告就使用，會造成全域物件汙染

# 資料型態

變數本身是沒有型態的

分為兩大類

型態間可以轉換，如 : a =123; b = String (a); 此時 b 的型態就會變成字串

## 原始型別 (Primitive Type)

- 數字 (Number)
同四則運算，並括號內先運算
    - a++ 與 ++a
    a++ 為 a 的值之後 +1
    ++a 為 a 的值先 +1 後回傳 a
    - NaN : Not a Number 不是一個數字的意思
    用來代表”不是數字”的**數字** (所以 NaN 的本質是數字)
- 字串 (String)
用單雙引號都可以, `` (此符號稱為 backtick ) 也可以，更可串接變數
- 真假值, 布林值 (Boolean)
只有 true 跟 false
- 空值 (Null) : 表示不存在，但用 typeof 去查會`顯示為 object`
- 未定義 (Undefined)
- 符號 (Symbol)

## 物件型別 (Object Type)

- 陣列 (Array)
- 函數 (Function)
- 物件 (Object)

### 強制轉型 (Type Coercion)

# 流程控制

## IF

### if

給予一個條件，若符合條件便執行某件事，若不符合則不執行

```jsx
if (條件) {
  符合條件便執行某事
}
```

### if … else …

符合條件執行某事，否則執行其他的事情

```jsx
if (條件) {
  符合條件執行
} else {
  不符合條件則執行另一件事
} 
// 若要增加 
if ( ){
} else if ( ) {
} else {
}
```

### 三元運算子

雖然可以使程式碼簡短，但要注意可讀性

### Switch

依多事件去判斷要執行那個事情

```jsx
let example = 值
switch (example) {
  case 條件1的值:
    執行某事
    break
  case 條件2的值:
    執行某事
    break
  default: //default 可寫可不寫，但建議要
    某事
    break
}
```

## 布林值

只有 true / false 沒有其他

### 視為 false 的值

0 / undefind / null / 空字串 / NaN

## 邏輯運算

### and / or / not

前後都要成立，寫法為 &&

前後其中一邊成立即可，寫法為 || 

代表”不等於”，寫法為 ! 如 :  !== (不等於)

## 補充

prompt (瀏覽器會跳出視窗請使用者輸入)
可設定一個 變數 = prompt()
由此獲得使用者輸入的值
如 : let value = prompt (”請輸入值”)

## 迴圈 Loop

### For 迴圈

- 寫法
    
    ```jsx
    for (let 變數 = 值; 變數 < 次數 ; 變數 = 變數 + 1 /* 每次動作後變數的值加1 */ ){
      每次要執行的動作
    }
    ```
中間為執行條件, 同 while 滿足條件便會執行

### While 迴圈

- 寫法
    
    ```jsx
    while (條件 /* 若符合條件就會執行 */) {
      每次要執行的動作
    }
    ```
    

### 比較

數量明確建議用 FOR
但原則上兩者都可以互換。

## 補充

重複字串 ( .repeat() )

> a.repeat(4)
< aaaa

> ruby.repeat(3)
< rubyrubyruby

# 函數

function 本身是值也是一種物件

## 定義函數

1. 用 function 宣告 並將此函數命名，在後方括號加入參數 (Parameter，如果有的話) 最後用大括號將欲直行的行為定義，模式如下 : 
function 函數的名子( 參數 ) { 
    此函數要執行的行為
 }
要使用時，用名子加括號即可，如 : 函數的名子()
    - 例子
        
        ```jsx
        function funcName(){
          console.log("範例")
        }
        ```
        
2. 可先宣告變數名稱，後將此變數指定函數給它，如 : 
const 函數的名子 = function(參數) { 
    此函數要執行的行為
 }
    - 例子
        
        ```jsx
        const funcName = function(){
          console.log("範例")
        }
        ```
        
    
    可改寫為 [箭頭函數 (Arrow Function)](https://www.notion.so/JavaScript-b4256c1ba56b4abcb8dbcb7e77bb496c?pvs=21) ，如 : 
    const 函數的名子 = () => { 
        此函數要執行的行為
     }
    
    - 例子
        
        ```jsx
        const funcName = () => {
          console.log("範例")
        }
        ```
        

### 兩種宣告差異 (1跟2)

下方用宣告變數並指定函數的方式，此函數為「匿名函數 (Anonymous Function)」
使用上沒有差異，唯一不同的是 : 使用匿名函數若在宣告前執行，會發生錯誤。

### [箭頭函數 (Arrow Function)](https://www.notion.so/JavaScript-b4256c1ba56b4abcb8dbcb7e77bb496c?pvs=21)

不只是 function 的縮寫，與 this 有關

## 使用函數

函數名要加上 () 才會執行。

### 參數 vs 引數 (Argument)

引數為執行時所帶入的參數，該參數的名子為引數，如圖所示 : 
function 函數名子 (參數) {
	欲執行的指令
}
函數名子 (引數) 

- 例子
    
    ```jsx
    function 函數名子 (參數) {
      console.log(參數)
    }
    函數名子(引數) // 螢幕會印出 引數
    ```
    

### 加入參數

可在括弧內加入參數，便可以改變執行的動作

- 例子
    
    ```jsx
    function funcName(method){
      if (method == 1) {
        console.log("參數為1")
      }  else {
        console.log("參數不為1")
      }
    } 
    
    > funcName(1)
    < 參數為1
    
    > funcName(54654)
    > 參數不為1"
    ```
    

參數的個數；
若參數有設置三個，但引數的數量不對，狀況會如下 :
有少，則少的那個位置的值會為 undefined
有多，則會被無視

若參數有設置預設值，如 : 
```jsx
function sayHi( a, b, c = “hi”) {
  console.log( a, b, c)
}
sayHi() //undefined, undefined, hi

```

## 回傳值 (Return Value)

函數最後要用 return 來將結果回傳 (代表這個函數最後的結果)，如 :

- 例子
    
    ```jsx
    function isAdult(age){
      if (age >= 18) {
        return true
      } else {
        return false
      }
    }
    isAdult(x) // 此時會依帶入的 x 來告訴你是 T 還是 F
    ```
    

在函式內若碰到 return 就會將控制權交還回去(可想成此函式直接變成回傳的那個值)，所以在下面的動作就不會執行。

所有的函數**都有回傳值**，即便沒有寫 return 也會回傳 **undefined**

# 陣列 (Array) 與物件 (Object)

## 陣列

用 中括號 定義陣列，如 : let array = [a, b, c]

可在裡面放入任何值，甚至再放入陣列也可以，稱為「多維陣列」(常見為兩層、三層以上則為少見)

### 陣列操作

陣列長度 : array.length //此為陣列內有幾個元素

取得元素 : 可用索引值 (index) 來操作，陣列從 0 開始操作 (第一個值)

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D", "E"]
    console.log(array[0]) // 會印出第一個值 A
    ```
    

新增元素 : push, pop, shift, unshift

可用 push (從最後面新增) 或是 unshift (從最前面新增)

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D"]
    console.log(array) // 會印出 ['A', 'B', 'C', 'D']
    array.push("X") 
    console.log(array) // 此時會印出 ['A', 'B', 'C', 'D', 'X']
    array.unshift("Y")
    console.log(array) // 此時會印出 ['Y', 'A', 'B', 'C', 'D', 'X']
    ```
    

可用 pop (從最後面抽出) 或是 shift (從最前面抽出)

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D"]
    console.log(array) // 會印出 ['A', 'B', 'C', 'D']
    array.pop() 
    console.log(array) // 此時會印出 ['A', 'B', 'C']
    array.shift()
    console.log(array) // 此時會印出 ['B', 'C']
    ```
    

修改元素 : 索引值, splice

直接使用索引值指定某個位置的值作修改

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D", "E"]
    array[1] = "X"
    console.log(array) // 會印出 ['A', 'X', 'C', 'D', 'E']
    ```
    

使用 splice, 在後方可設定三個參數；從哪開始，刪除幾個，放入值

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D", "E", "F"]
    array.splice(1, 2, "X")
    console.log(array) // 會印出 ['A', 'X', 'D', 'E', 'F']
    array.splice(3, 0, "Y")
    console.log(array) // 會印出 ['A', 'X', 'D', 'Y', 'E', 'F']
    ```
    

組裝陣列 : concat

- 直接看範例
    
    ```jsx
    let array1 = ["a", "b", "c"]
    let array2 = ["x", "y", "z"]
    let newArray = array1.concat(array2)
    console.log(newArray) // 會印出 ['a', 'b', 'c', 'x', 'y', 'z']
    ```
    

### 相關函數

陣列內有無某元素 : 

.indexOf( ) → 小括號內的值在陣列當中的索引值是多少，若有多個相同元素則會回傳第一個找到的索引值，若此元素不存在則此索引值為 -1。
.includes( ) → 小括號內的值是否存在於陣列之中。依具有無回傳 true / false ；但 IE 不支援。

- 範例
    
    ```jsx
    let array = ["A", "B", "C"]
    console.log(array.indexOf("B")) // 會印出 1
    console.log(array.indexOf("X")) // 會印出 -1
    console.log(array.includes("B")) // 會印出 true
    console.log(array.includes("X")) // 會印出 false
    ```
    

印出陣列內的每個元素 : 

用 for 迴圈印出

- 範例
    
    ```jsx
    let array = ["A", "B", "C", "D", "E", "F"]
    for (let i = 0; i < array.length; i++){
      console.log(array[i]) 
    }
    ```
    

forEach → 後面接一個 function (此函數稱為 「[callback 回呼函數](https://www.notion.so/JavaScript-b4256c1ba56b4abcb8dbcb7e77bb496c?pvs=21)」)，forEach會將陣列的值一個一個的丟入此函數執行。

- 範例
    
    ```jsx
    let heros = ["A", "B", "C", "D", "E", "F"]//建議外面的陣列英文名為複數 
    heros.forEach(function(hero){             //則forEach後的函式參數設定名用單數
      console.log(hero)                       //表示為將陣列的每個值，各自都投入函數內執行
    })                                        //故此例印出的皆是單一個值。
    //將回呼函式的形式改寫成箭頭函式也可以，如下
    heros.forEach((hero) => {
      console.log(hero) 
    })
    ```
    

找尋符合條件的元素 : 

.find() → 在後面的括號內放入 function 並會將值迭代

find 只會找第一個符合的就停止, 若沒回傳就停下

- 範例
    
    ```jsx
    let array = ["AA", "B", "CCC", "DD"]
    array.find(function(value){
      if (value.length >= 2) {
        console.log(value)}	
    }) // 此時會分別印出 AA, CCC, DD (因為是迭代，所以會印出三行(作三次的意思)
    //若改寫成
    let val = array.find(function(value)){
      return value.length <= 2
    }) 
    console.log(val) //只會顯示 AA (因return 會中止迭代
    //若是都找不到, 則會回傳 undefined
    //新版
    const a = [1, 2, 3, 3, 3, 3, 4, 5, 6]
    const result = a.find((x) => {
      console.log(x) //只會出現 1, 2, 3 就停下來了
      return x == 3 // 此時result的值為 3 (第一個的3)
    })
    ```
    

對某個元素作些事，後蒐集成「新的陣列」

- .map 範例
    
    ```jsx
    let array = ["A", "B", "C"]
    let result = array.map((h)=>{
      return h.repeat(5)
    })
    console.log(result) // [AAAAA, BBBBB, CCCCC]
    ```
    

對每個元素作判斷，將符合條件的元素蒐集成「新的陣列」

- .filter 範例
    
    ```jsx
    let array = ["AAAA", "B", "CCC", "DD", "EEEEE", "FFFF"]
    let result = array.filter((h) => {
      return h.length >= 4
    })
    console.log(result) // ['AAAA', 'EEEEE', 'FFFF']
    ```
    

將矩陣內的值累加 : 後方接兩個參數，第一個是累加值 (起始值 / 目前總和的值)，第二個為每次丟入的值，後方函數

.reduce() → 後方接兩個參數，第一個是累加值，第二個為每次丟入的值；並於後方函數設定第一次的累加值，若沒設定則會拿第一個值當第一次的累加值

- .reduce 範例
    
    ```jsx
    /*格式為
    array.reduce(function( acc/累加值.aka目前加總的值/ ,cv/現在的值.aka這次要丟入動作的值/){
      return acc + cv
    }, acc/此參數要放入第一次起始的累加值/)
    */
    let array = [5, 2, 8, 3, 3, 1]  // 此陣列加總值為 22
    let result = array.reduce((acc, cv) => {
      return acc + cv
    }, 20)              // 若此處 20 的設定為 0, 或未設定則答案會是 22
    console.log(result) // 會印出42
    ```
    

### 參照

```jsx
let a = [1, 2, 3]
let b = a
console.log(b) //[1, 2, 3]
b[0] = "x"
console.log(a) //['x', 2, 3]
console.log(b) //['x', 2, 3]
let c = 1
let d = c
console.log(d) // 1
c = 2
console.log(c) // 2
console.log(d) // 1
```

## 物件

與陣列的差別 : 物件有屬性跟行為
用 大括號 定義物件，並設定 key + value 並且每一組用逗號隔開，如 : 

```jsx
const dog = {
  name : "富貴",
  color : "白色",
  attack : function (){
    console.log ("汪汪!!!")
  }
}
```

呼叫方式為

1. 物件名.key 如 : [dog.name](http://dog.name) // 會顯示富貴
2. 物件名[”key”] 如 : dog[”name”] // 中括號裡面需用字串

增減屬性

- 新增屬性 : 直接打出來設定即可，如 : dog.type = “馬爾”
- 刪除屬性 : 用關鍵字 delete ，如 delete dog.age

# DOM (Document Object Model)

DOM : 文件物件模型

需抓取 html 元素時可用 getElement 或是 querySelector

## getElement 系列

須帶入該元素的 ID 或是 ClassName 

document.getElementById ( ) // 括弧內放欲選取的元素 ID 名
document.getElementByClassName ( ) // 括弧內放欲選取的元素 class 名

## querySelector 系列

依 CSS 選取器的方式選取，前綴的符號 ( # 或 . ) 不能省略 (因要表示選取哪個層級)

document.querySelector ( ) // 選取 ID 用 # 字號；選取 class 用 . 符號，如 : #title

document.querySelectorAll ( ) 

## 選取細談

1. 若依 id 去取，都會是元素 (一個)，如 :
let d1 = document.getElementById( ”ex-1” )
let d2 = document.querySelector ( ”#ex-1” )
console.log(d1) 跟 console.log(d2) 都是一樣的東西
2. 若依 class 去取，會得到元素們 (全部)，如 :
let t1 = document.getElementById( ”ex2” )
let t2 = document.querySelector ( ”.ex2” )
則會得到
console.log(t1) // HTMLCollection
console.log(t2) // NodeList
此二者很像，但不一樣
- 用 getElement 所抓出來的元素們為 HTMLCollection，其意涵為「元素」
而 querySelector 則是 NodeList，其意涵為「節點 (node)」
本質上是不同東西，但此二者同為集合 (非陣列)，但亦有所不同
- 所以抓取元素，且不只有一個元素時，此時抓取出來的資料會是「一個集合」，很像陣列，但不是陣列，所以大部分的陣列函數不能使用

若頁面有多個同名 id ，只會抓取第一個元素做操作 (要避片命名同一 ID )

HTML 的標籤 id 屬性，若在JS內無設定變數，可直接用此 id 名稱當作 「變數」 **但絕對不要這樣用**

element 與 node 差別 : 
element 本身就是一種 node 但是是特別版本的 node ，所以節點的功能元素都有，盡量都使用 element 的方式

## DOM 操作

### 動態插入標籤 (由 JS 插入 HTML 標籤)

1. const h = document.createElement(”標籤名”) → 先設置變數並創立標籤，同<標籤></標籤>
2. h.textContent = “hi” → 並在標籤內插入文本，同 <標籤>hi</標籤>
3. someDiv.appendChild(h) → 創立的標籤與文本只存在於記憶體中，需再放入其他元素之中使其渲染出來，如其他的 div 元素等，此新增元素則會放在最後面。

簡單說, 創造元素(標籤) → 輸入內文 → 再放入其他已存在的元素之中

### 刪除DOM

1. 先抓取欲刪除的元素的父元素
2. 用 父元素.removeChild( ) 來將其刪除
3. 或是 該元素.remove 刪除 即可

### 找尋 元素

找父層 : 該元素.parentElement 或是 該元素.parentNode
找子層 : 該元素.childNodes 或是 該元素.children
找平行層 : 該元素.previousElementSibling (前一個) / 該元素.nextElementSibling (後一個)
若是以取 node 的方式為 : 該元素.previousSibling (前一個)  / 該元素.nextSibling (後一個)

### 指定位置安插 DOM

1. 父元素.insertAdjacentElement(”位置” , 要插入的元素)
如 : ul.insertAdjacentElement(”beforeend” , li) // 會排在達爾後面
2. 或是將標籤已文字設為變數，再用父元素.insertAdjacentHTML(”位置”, 該變數)來插入

![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/2ab50771-fd84-4380-b24c-087641c2be2b/cb4e0354-aa93-4c70-a976-5839cf63cf0c/Untitled.png)

# 事件

瀏覽器在執行的時候會發生許多「事件 (event)」，如 : 點擊、滑鼠移動……等。

## 監聽器

若瀏覽器需要知道發生了什麼事件，則需要設置事件監聽器 (Event Listener)

```jsx
//假設 html 檔案內已有設置按鈕 <button id="btn">按鈕</button>
//回 JavaScript 的檔案內，先將按鈕標記出來
const btn = document.querySelector("#btn")
//替此按鈕加上監聽器
btn.addEventListener("click", funtion(){ // 第一個寫監聽什麼事件(此處為按下 click )
  console.log("已按下按鈕")               // 第二的地方將函數設為引數，表示按下後執行該事情
})
```

### 回呼函數

此函數為非同步的一種；簡而言之，當前置事情發生的時候，再執行該函數事件即可

### 執行 JavaScript 前置細項

若將 JS 放在 HTML 的 <head> 標籤內，因網頁尚未解析 <body> 而使元素不存在而變成空值 (null) 而無法掛上監聽器。解決方法有四 : 

1. 在 html 最尾端再載入 .js
2. 監聽頁面，待 DOM tree 建立完成後再去執行其他事件
    - 範例
        
        ```jsx
        document.addEventListener("DOMContentLoaded" , () => {  //寫在第一行，表DOM tree完成後再執行後方函數
        	//此處即可寫入用 querySelector 去抓元素
        })
        ```
        
3. 欲執行的事情寫在 DOM 上 (不好維護並且無法重複利用，不建議這麼做)
4. 在 HTML 的 <script> 標籤內 加入 defer 代表延遲載入
    - 範例
        
        ```jsx
        <script src='scripts/app.js' defer></script>
        ```
        

## 直接在物件上設定事件 (on 系列)

在按鈕上直接加入 ”被點擊時” 的狀況，如 : btn.onclick = function (){ console.log(”被點擊了”)}

此寫法跟監聽器沒有差別，但若有重複的情況，只會有最新的被反應出來 (前指令會被覆蓋)

而監聽器則可以疊加狀態，觸發時皆會執行。

## 預設行為

像超連結的預設行為會將頁面轉置該超連結的網站，但若只是想確認該「點擊」事件有無正常運作，則可以使用 preventDefault 來停止預設行為

- 範例
    
    ```jsx
    const link = document.querySelector('#link') // 此處假設 html 已有設置 ID 為 link 的超連結標籤
    link.addEventListener('click', (e) =>{ // 此處的 e 沒有作用，只是代表點擊這件"事件"
      e.preventDefault()  //此處意為「預防點擊後的預設行為」，也就是 link 的跳轉頁面，故點擊後不會跳轉
      console.log("以點擊按鈕")
    })
    ```
    

# ES6 / ES2015 語法補充

## 字串與變數組合

加入反單引號 (backquote / backtick) : 使字串內可加入變數，如 : 
ES6 之前 : console.log( ”你好，我的名子是” + name + “，今年” + age + ”歲” )

ES6 之後 : console.log( `你好，我的名子是 ${name}，今年 ${age}歲` )

## 箭頭函數

- 例子
    
    ```jsx
    const addNumber = function (a, b) {  //前，普通的匿名函式寫法
      return a + b
    }
    // 下為改寫箭頭函式
    const addNumber = (a, b) => {  
      return a + b
    }
    // 若該函式只有一行，更可將 return 省略
    const addNumber = (a, b) => a + b 
    ```
    

但箭頭函數不是一般 function 的簡寫

## 物件簡寫

- 如果 key 跟 變數的名子 一樣，可以只寫一個代表
    
    ```jsx
    let name = "富貴"
    let age = 10
    let dog = {
      name,
      age,
    }
    ```
    

## 解構

- 可一口氣將物件的值，分別指定變數，函式也可以
    
    ```jsx
    const dog = {
      name: "富貴",
      age: 10,
    }
    /* 原本若要拿出物件屬性會依以下
    let name = dog.name
    let age = dog.age
    console.log(name, age)*/
    let { dogName, age } = dog  //解構寫法 (將 key 的 name 當中的值指定變數給 dogName，age 的值指定給 age
    console.log(dogName, age) //與上方結果相同
    ```
    

## 點點點 (…)

### 展開

- … 在陣列裡有展開的效果
    
    ```jsx
    const H1 = ["1", "2", "3"]
    const H2 = ["X", "Y", "Z"]
    const HAll = [...H1, ...H2] //效果等同 H1.concat(H2)
    console.log(HAll) // ["1", "2", "3", "X", "Y", "Z"]
    ```
    

### 剩下全收

- 將沒指定到的參數通通含括，也可用在函數，如 :
    
    ```jsx
    const array1 = ["a", "b", "c", "d", "e"]
    //用解構來定義 na1, na2 兩個新變數 
    let [na1, ...na2] = array1 
    console.log(na1, na2) // a   ["b", "c", "d", "e"] 分為 a 跟 剩下所組成的陣列
    //函數也可以
    function sayHello(user, ...other){
      console.log(user)
      console.log(other + "YO")
    } //正常只會回應 '1', '2'，剩下拋棄，加... 則會依第二個處理
    sayHello('1', '2', '3', '4', '5') // 1 跟 2, 3, 4, 5YO (若沒加YO 則會回傳 1 跟 陣列['2', '3', '4', '5'])
    ```
    

# 抓取網路資料

[API](https://medium.com/itsems-frontend/api-%E6%98%AF%E4%BB%80%E9%BA%BC-restful-api-%E5%8F%88%E6%98%AF%E4%BB%80%E9%BA%BC-a001a85ab638) (Application Programming Interface) : 應用程式”**介面”**，定義多個軟體中介之間的互動並可進行呼叫 (call) 或請求 (request)。

## 資料存取的方法

- GET
- POST
- PUT
- PATCH
- DELETE

### RESTFul (Representational State Transfer) 表現層狀態轉換

REST 是一種設計風格，RESTful 只是轉為形容詞，此風格主要由三種元件組成 : 

1. 名詞 (Nouns) : 定義資源位置的URL
2. 動詞 (Verbs) : 對資源要做的動作 (會將動作藏在 HTTP 的 Method 裡面)
3. 資源呈現方式 (Content Types) : 資源表現方式，目前最常用的為 JSON

### 資料傳輸的格式

- XML
- CSV
- JSON (JavaScript Object Notation)
- AJAX (**A**synchronous **J**avaScript **a**nd **X**ML) 非同步JS與XML技術 : 非語法或技術，而是技術的綜合體。

### 同步 vs 非同步

同步比較像打電話，非同步像傳訊息。

可參照下方 async / await

### CORS (Cross-Origin Resource Sharing) **跨來源資源共用**

一種存取機制，防止有心人士惡意存取資料

基本上無法解決，只能請對方開啟 CORS

## 使用 XMLHttpRequest 函數

- 1.先定義 req 物件 (由 XMLHttpRequest 由此物件來取得伺服器端的資料)
2.發出 request (請求)，需叫用 HTTP request 類別的 open() 及 send() 兩個方法
3.設置監聽器，只要請求出去，便會加資料抓回來
4.將資料轉換成 JSON 格式
5.此時可用陣列操作物件來使用資料 (印出資料抬頭等)
    
    ```jsx
    const api = ' api網址 '
    //STEP 1
    const req = new XMLHttpRequest()
    //STEP 3
    req.addEventListener('load', () =>{  //此時回傳的是"字串"，需轉換成 JSON 物件
      const posts = JSON.parse(req.responseText) //STEP 4 將其轉換成 JSON
      posts.forEach((post) => {
        console.log(post.title) 
      })
    })
    //STEP 2 
    req.open('GET', api)
    req.send()
    ```
    

## 使用 fetch 函數

- 1.直接使用 fetch 抓取 api ，並 (依該回傳資料繼續動作用 then) 依抓取的資料 (Promise 物件) 改由 JSON 格式回傳回來
2.再繼續由該 JSON 物件，依陣列操作方法操作 (範例內為印出標題抬頭)
    
    ```jsx
    const api = ' api網址 '
    //STEP 1
    fetch(api).then((response) => {
      return response.json()
    }).then((data) => { //STEP 2
      data.forEach((d) => {
        console.log(d.title)
      })
    }) 
    ```
    

## 使用 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('此行會先行')
    
    ```
    

# jQuery

1. 可使用檔案下載後再載入，或是用 CDN 的方式載入框架
2. 其好處是若瀏覽器不支援某些 JS 用法 jQuery 可提供類似方法應對
3. 基本上都是以 $ 開頭來執行
    - 如 : 開頭待 DOM 解析完成可改用 jQuery 改寫
        
        ```jsx
        document.addEventListener("DOMContentLoaded",() => {
        }
        // jQuery 改寫為
        $().ready(() =>{
        })
        ```
        
    
    選取元素 : 以 ID 為 hero 為例 const hero = $(”#hero”)
    

## 抓取資料的方式

- 用 $ajax 的方式
    
    ```jsx
    const url = ' api網址 '
    //STEP 1 (先設立物件，此處[用ES6的語法](https://www.notion.so/JavaScript-b4256c1ba56b4abcb8dbcb7e77bb496c?pvs=21))
    $.ajax({ url }).done((posts)=>{
      console.log('載入 DOM 完成後，顯示此行')
      posts.forEach(post => { //STEP 2 該回傳值已是JSON格式
        console.log(post.title)
      })
    })
    ```
    

## jQuery vs JS/ES6

普通網站 jQuery 就足夠了，Vue 跟 React 適合更高互動的網站。但 ES6 以後基本上都很好寫，支援度也夠，就可以斟酌 

### Vanilla.js 香草 JS

效能最好,跨瀏覽器支援度高 (就是原生的 JS ，所有的東西都是原生 JS 所衍生的)