---
# System prepended metadata

title: JS 學習筆記

---

> 如果有記憶吐司就好了...
# JS 學習筆記

## 陣列

宣告一個陣列的方式用[]包資料,每筆資料用逗號隔開
```=
let colors = ["red","blue","black"];
```




讀取陣列裡面的資料,陣列的第一筆從0計算
```=
console.log(colors[0]);
// 變數colors裡面的陣列第0筆,回傳值為red。
```

### push()
將資料加入到陣列裡面的最後一筆,
使用時機:排名搶頭香
```=
colors.push("pink");
```

### unshift()
將資料加入到陣列裡面的第一筆
使用時機:最新的放最前面ex:新聞
```=
colors.unshift("pink");
```

### pop()
將陣列內的最後一筆資料刪除
```=
colors.pop();
```


### shift()
將陣列內的第一筆資料刪除
```=
colors.shift();
```


### splice(索引位置,數量)
將陣列內的其中一筆或是一個範圍內的資料刪除
使用時機:待辦事項做完要刪除的時候
```=
let colors = ["red","blue","black"];
colors.splice(1,2);
// 括弧內的1為陣列內的第1筆blue開始,括弧內的2為從blue開始刪除2筆資料,所以將刪除blue及black共兩筆資料
```

### concat()
concat 是用於串接兩個陣列，串接的結果會透過回傳值取得，並不會套用至原有的陣列
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];

let newArray = array.concat(["政憲","羚貽"]);
console.log(newArray);
// newArray回傳  ['小明', '杰倫', '漂亮阿姨', '小美', '政憲', '羚貽']
// array 依然是 ["小明", "杰倫", "漂亮阿姨", "小美"]
```

### include()
include 可以用來檢查陣列中是否包含特定值，結果會透過回傳的方式取得
```=
et array = ["小明","杰倫","漂亮阿姨","小美"];

console.log(array.includes('漂亮阿姨')); // true
console.log(array.includes('阿明'));    // false
```

### indexOf()
與 include() 運作上相當類似，僅不過 include() 是回傳 true、false，而 indexOf 則是回傳該值的索引位置
```=
console.log(array.indexOf('漂亮阿姨')); // 2
console.log(array.indexOf('阿明'));    // -1
// 當值如果不存在於陣列中，則會回傳 -1
```

### join()
可以將陣列中的值轉變為字串，並且加入特定字元作為值相間的符號
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];

console.log(array.join(', ')); // 小明, 杰倫, 漂亮阿姨, 小美
console.log(array.join('/')); // 小明/杰倫/漂亮阿姨/小美
```
簡單的語法，但是搭配 ES6 中的 Template literal 可以用極短的程式碼組合出複雜的字串結構
```=
let array = ["小明","杰倫","漂亮阿姨","小美"];

let newHTML = `<ul>${ array.map((item)=> `
<li>${item}</li>`).join(' ')}
</ul>`;
console.log(newHTML);

// 回傳
<ul>
  <li>小明</li> 
  <li>杰倫</li> 
  <li>漂亮阿姨</li> 
  <li>小美</li>
</ul>
```


## 物件

宣告一個物件,用 **{}** 包資料,裡面可建立多筆屬性,屬性名稱放左邊,用冒號做賦予,右邊則放入值,物件內的每筆屬性用逗號隔開,每筆物件的最後一筆屬性可以不加逗號。
```=
let teamA ={
  name:"Jasper",
  age:32,
  height:168
};
```

### 如何讀取物件內屬性的值
1. 用 **.** 來指定要讀取哪一筆屬性的值
```=
console.log(teamA.name);
// 讀取變數teamA物件內屬性為name的值,回傳為Jasper
```

2. 用 **[]** 裡面加單/雙引號來取指定屬性的值
使用時機:不允許讀取的狀態,遇到特殊字元的時候ex:屬性開頭為數字

```=
console.log(teamA['name']);// 取值的方式

let teamA ={
  name:"Jasper",
  age:32,
  height:168
};

let thatName = "name"; 
// 宣告一個新的變數並賦予物件內name屬性來取值

console.log(teamA.thatName);
// 用.來取值,僅會幫您找到teamA物件裡面符合的屬性,所以沒有在teamA內找到符合thatName的屬性,回傳undefined

console.log(teamA[thatName]);
// 用[]來取值,除了幫您在teamA物件內找尋之外,還會在記憶體內找尋變數是否有被賦予符合的屬性,回傳"Jasper"
```
若是用[]取物件內的屬性,需加單/雙引號
```=
console.log(teamA["name"]);
```

### 如何新增物件內的屬性及資料
用 **.** 來新增屬性並用等於賦予值
```=
teamA.weight = 57;
// 於物件teamA裡面新增weight的名稱並賦予值57
```

用 **[]** 包單/雙引號來新增屬性或特殊字元的屬性ex:數字開頭的屬性名稱

```=
teamA["0"] = false;
// 於物件teamA裡面新增屬性名稱為0並賦予值false
```

### 如何變更物件內的資料
用 **=** 重新賦予值,或是依照語意運算本來的屬性
```=
// 今天量體重發現少了一公斤
teamA.weight = 56;
or
teamA.weight -= 1;
```
## 函式 function
宣告一個函式名稱,後面 **()** 為參數, **{}** 內為執行後要做的動作,用 **morningAction()** 來呼叫函式
```=
function morningAction(){
    console.log('起床');
    console.log('刷牙');
    console.log('洗臉');
    console.log('出門');
};
morningAction();  //執行函式
// 回傳 起床、刷牙、洗臉、出門
```
### 函式內也可以執行函式
宣告另一個函式放入要呼叫的函示內
```=
function morningAction(){
    console.log('起床');
    cleanHead();
    console.log('出門');
};
function cleanHead(){
    console.log('刷牙');
    console.log('洗臉');
};
morningAction();  //執行函式
// 回傳 起床、刷牙、洗臉、出門
```
### 函式參數介紹
函式的()內放入參數,執行函式時可帶入參數的值

```=
function number(num){
    console.log(num);
};
number(1);
// 回傳 1
```

### 使用參數相加
**()** 內可輸入多個參數,須用 **,** 隔開
```=
function add(num,num2){
    console.log(`總共${num+num2}元`);
};
add(1,2);
// 回傳總共3元
```

### 參數的值只存在在{}內
```=
function add(num,num2){
    console.log(num,num2); //回傳1、2
};
add(1,2);
console.log(num); // 回傳錯誤
```
### return回傳至指定的地方
若沒有用return,即使宣告一個變數並賦予函式給予參數,雖然函式會執行帶入的參數,但是並不會將結果回傳至變數,僅留在 **{}** 內
```=
function testScore(mathScore,englishScore){
    console.log(mathScore+englishScore);
};// 回傳170

let JasperTotalScore = testScore(90,80);
console.log(JasperTotalScore); 
// 回傳unfefined
```
宣告一個變數並賦予函式給予參數,執行函式後使用return將 **{}** 內執行的結果,回傳至被賦予的函式
```=
function testScore(mathScore,englishScore){
    return mathScore + englishScore;
};

let JasperTotalScore = testScore(90,80);
console.log(`Jasper總分為${JasperTotalScore}分`);
// 回傳Jasper總分為170分
```

## DOM 選取網頁元素

### querySelector選擇器
只會選擇網頁內最前面第一個dom。
```htmlembedded=
// html環境
<p>我被 el 選到了</p>  
<p>我沒有被選到</p>
```
```js=
let el = document.querySelector("p")
//只會回傳第一個符合選取條件的元素
```
可以選取帶有 id 或 class 的元素
```htmlembedded=
// html環境
<body>
    <p id="targetID"> 我被 elementID 選到了</p>
    <p class="targetClass">我被 elementClass 選到了</p>
</body>
```

```=
let elementID = document.querySelector("#targetID");
let elementClass = document.querySelector(".targetClass");

// 宣告一個變數,用選擇器選取html的.main
```
可以用類似 CSS 的撰寫方式選取
```htmlembedded=
// html環境
<div id="targetID">
  <p>我被 elementID 選取到了</p>
</div>

<!-- 以下是 span 被選取到 -->
<div class="targetClass">
    <p>
        <span>我被 elementClass 選取到了</span>
    </p>
</div>
```
```js=
let elementID = document.querySelector("#targetID > p");
let elementClass = document.querySelector(".targetClass > p > span");
```

### textcontent 

透過 textContent 可以取得 DOM 元素內的 「純文字內容」，HTML 會被忽略 (請注意「純文字內容」有包含換行以及空格)

```htmlembedded=
<div class="targetClass">
  <p>取得這個 p 標籤的純文字</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass p");
console.log(targetClass.textContent);
```
結果 (以下為 CodePen console 的結果):

![](https://i.imgur.com/VltAXej.png)


#### 可以透過 textContent 替換 DOM 元素內的內容，需要注意以下幾個重點:
    1. 原先的所有內容都會被清空 (包含 HTML 標籤)
    2. 新的內容將被瀏覽器解析成「純文字」，不會保留 HTML 標籤的特性。

```htmlembedded=
<!--  以下的 p 標籤會被清空，替換成純文字 "<h3>修改後的內容</h3>" -->
<div class="targetClass">
  <p>替換這個 p 標籤</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
targetClass.textContent = "<h3>修改後的內容</h3>";
```
結果 1: 
(網頁渲染出的畫面)
![](https://i.imgur.com/MnrUGTh.png)

結果 2: 
(修改後的 HTML 結構)
![](https://i.imgur.com/MPM2pVi.png)


#### textContent 可以跟變數混合使用

```htmlembedded=
<div class="targetClass"></div>
```
```js=
let targetClass = document.querySelector(".targetClass");
let score = 100;
targetClass.textContent = `<p>小華的成績為 ${score} 分</p>`
```

結果 1:
(網頁渲染出的畫面)
![](https://i.imgur.com/GH77RQV.png)

結果 2: 
(修改後的 HTML 結構)
![](https://i.imgur.com/ZrGcOr2.png)

### innerHTML
#### 透過 innerHTML 可以取得 DOM 元素內的「HTML 內容」

```htmlembedded=
<div class="targetClass">
  <!--  註解、換行、空白也包含在內  -->
  <p>HTML 標籤的內容也被選取</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
console.log(targetClass.innerHTML);
```

結果 (以下為 Chrome console 的顯示結果):
![](https://i.imgur.com/o9jjMoO.png)



#### 可以透過 innerHTML 替換 DOM 元素內的 HTML，需要注意以下幾個重點:

1. 原先的所有內容都會被清空
2. 新的內容將被瀏覽器解析成「HTML」，也就是說會保留 HTML 標籤的特性。


```htmlembedded=
<!-- 以下的 p 標籤會被清空 -->
<div class="targetClass">
  <p>替換這個 p 標籤</p>
</div>
```
```js=
let targetClass = document.querySelector(".targetClass");
targetClass.innerHTML = "<h3>修改後的內容</h3>";
```

結果 1: 
(網頁渲染出的畫面)
![](https://i.imgur.com/jlK0C6J.png)

結果 2: 
(修改後的 HTML 結構)

![](https://i.imgur.com/2ilR3vL.png)


### innerHTML 可以跟變數混合使用

```htmlembedded=
<div class="targetClass"></div>
```
```js=
let targetClass = document.querySelector(".targetClass");
let score = 100;
targetClass.innerHTML = `<p>小華的成績為 ${score} 分</p>`
```

結果 1:
(網頁渲染出的畫面)
![](https://i.imgur.com/Qz857qD.png)

結果 2: 
(修改後的 HTML 結構)

![](https://i.imgur.com/El6951M.png)
```js=
main.innerHTML=`<h1>789<h1>`;

// 將html內的.main的架構都可以重新編輯,包含其他標籤
```

### getAttribute, setAttribute 應用 

以下連結為 HTML 的屬性列表，可以透過 getAttribute, setAttribute 操作這些屬性。
https://developer.mozilla.org/zh-TW/docs/Web/HTML/Attributes

### getAttribute

#### 使用 getAttribute 可以回傳一個元素上的指定屬性值，語法如下:

```js=
element.getAttribute("屬性名稱");
```
**範例**:

HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
JS
```js=
let element = document.querySelector('#targetId');
console.log(element.getAttribute('id'));
```
結果:
![](https://i.imgur.com/DvAMFov.png)

#### 使用 getAttribute 取用屬性時，如果指定的屬性不存在，則會回傳  `null` 或 `""`。

HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
JS
```js=
let element = document.querySelector('#targetId');
console.log(element.getAttribute('name')); // 由於 name 屬性不存在，因此會回傳 null
```
結果:
![](https://i.imgur.com/0bfxvG4.png)

### setAttribute
#### 可以使用 setAttribute 新增屬性上去，語法如下:
```js=
element.setAttribute("屬性名稱", "屬性值");
```
範例:
HTML
```htmlembedded=
<div id="targetId">目標 Id</div>
```
CSS
```css=
.colorRed{
   color: #FF0000;
}
```
JS
```js=
let element = document.querySelector('#targetId');
element.setAttribute('class', 'colorRed')
```
結果 (以下為網頁渲染畫面):
![](https://i.imgur.com/F53xtGb.png)

### querySelectorAll選擇器
回傳的是一個節點列表的陣列
```htmlembedded=
// html環境
<body>
   <a herf="#">連結</a>
   <a herf="#">連結</a>
</body>
```
```js=
const myLink = document.querySelectorAll('a');
// querySelectorAll回傳的是陣列[a,a]
myLink.setAttrebute[0]("herf","http:yahoo.com.tw")
// 選取陣列第一筆用[0]
myLink.setAttrebute[1]("herf","http:google.com.tw")
// 選取陣列第二筆用[1]
```

### 表單元素的取值方式

```htmlembedded=
// html環境
<body>
  <input type="text" class="txt" value="你好嗎">
</body>
```
```js=
const txt = document.querySelector(".txt");

console.log(txt.value);
// 回傳 你好嗎

txt.value = "Hello"
// 將你好嗎改成Hello
```

```htmlembedded=
// html環境
<body>
 <select class="list">
  <option value="高雄市">高雄市</option>
  <option value="台中市">台中市</option>
 </select>
</body>
```
```js=
const list = document.querySelector(".list");
// 選取select的list

console.log(list.value);
// 回傳 高雄市

list.value = "台中市";
// 將字面改成台中市

console.log(list.value);
// 回傳 台中市
```

### 事件 event
```htmlembedded=
// html環境
<body>
  <input type="button" class="btn" value="點擊">
  // 建立一個按鈕
</body>
```
```js=
const btn = document.querySelector(".btn");

btn.addEventListener("click",function(e){
   console.log("你已經被點擊了");
})
// 監聽這個按鈕,當被按下時執行特定行為

```
**加法、減法**
```htmlembedded=
// html環境
<body>
  <input type="button" class="btn" value="加法">
  <input type="button" class="btn2" value="減法">
  <h1 class="add">0</h1>
  <h1 class="minus">0</h1>
</body>
```
```js=
// 加法
const btn = document.querySelector(".btn"); 
// 宣告一個變數,賦予選擇上面class="btn"
const title = document.querySelector(".add");
// 宣告一個變數,賦予選擇上面class="add"
let count = 0;
// 宣告一個變數,賦予值為0

btn.addEventListener("click",function(e){
  count += 1;
  title.textContent = count;
});
// 設立監聽器事件名稱為click
// 當點擊按鈕"加法"
// 則執行函式count += 1
// 並將add的值賦予為count
// 每點擊一次add的值加1


//減法
const btn2 = document.querySelector(".btn2");
const title2 =document.querySelector(".minus");
let count2 = 0;

btn2.addEventListener("click",function(e){
  count2 -= 1;
  title2.textContent = count2;
})
```
### 透過nodeName了解目前DOM的HTML位置
```htmlembedded=
// html環境
<body>
  <input type="button" class="btn" value="點擊">
</body>
```
```js=
const btn = document.querySelector(".btn");

console.log(btn.nodeNamne);
// 回傳 INPUT
```
### etarget搭配nodeName的節點,抓到你預期要做的事
了解到不用每個DOM都綁監聽,可以將外層綁監聽,內層就都會有效果
```htmlembedded=
// html環境
<body>
    <ul class="list">
        <li>標籤</li>
        <li>標籤<input type="button" class="btn" value="按鈕">
        </li>
    </ul>
</body>
```
```js=
const list = document.querySelector(".list");
list.addEventListener("click",function(e){
    console.log(e.target.nodeName);
    if(e.target.nodeName == "INPUT"){
        console.log("你點到我了");
    }
});
// 當點擊到list的範圍則觸發console.log(e.target.nodeName);
// 回傳該範圍的DOM

// 當點擊到INPUT則觸發console.log(e.target.nodeName)+函式
// 回傳INPUT 及 你點到我了
```
### 用preventDefault取消預設觸發的行為
```htmlembedded=
//  html環境
<body>
    <a href="https:www.yahoo.com.tw/">連結</a>
    <h1></h1>
</body>
```
```js=
const myLink = document.querySelector("a");

myLink.addEventListener("click",function(e){
    e.preventDefault(); // 停止網頁跳轉過去yahoo
    console.log("點擊到我了"); // 回傳 點擊到我了
    document.querySelector("h1").textContent = "hello";// 賦予h1內的文字hello
});
```
### data-xxx也可以被選取來使用
除了 `.getAttribute` 以外， `data-xxx`  也可以用 `document.querySelector` 選取，例如:

HTML
```htmlembedded=
<p class="alertMsg" data-title="信箱"></p>
<p class="alertMsg" data-title="密碼"></p>
```
取得 「data-title="信箱"」p 標籤的方式有兩種:

JS
```js=
// 1
document.querySelectorAll('[data-title]')[0];

// 2
document.querySelector("[data-title='信箱']");
```

另外，也可以透過事件綁定來取得 `data-xxx`，例如:

HTML
```htmlembedded=
<p class="alertMsg" data-title="信箱">點我會顯示 dataset</p>
```
JS
```js=
let alertMsg = document.querySelector('.alertMsg');
alertMsg.addEventListener('click', function(e) {
    console.log(e.target.dataset.title);
})
```

## forEach

forEach() 是屬於 **「陣列」** 的方法，會將陣列內的每個元素一一傳入，並執行給定的函式一次。 forEach() 內的函式常見會帶有三個參數，以下為用法示例:
```js=
let data = ["a", "b", "c"];

// 參數 item 代表陣列中目前正在被處理的那個元素
// 參數 index 代表陣列中目前正在被處理的那個元素的索引值
// 參數 array 代表被處理的陣列本身，在此為 data
data.forEach(function(item, index, array){
    console.log(item, index, array);
})
```
執行結果:
![](https://i.imgur.com/NuRNgjX.png)



**在 forEach() 函式內用 return 是無效的。除非程式碼有誤，否則並沒有中止 forEach() 的辦法**

```js=
let data = ["a", "b", "c"];
// 
data.forEach(function(item, index, array){
    console.log(item, index, array);
    return; // 程式碼會忽略這個 return
})
```

## 表單取值
### `.value`,`.getAttribute('value')` 觀念

`.value` 取出的值是「字串」
這邊以 input 的 value 取值為例，請觀看以下範例:

HTML
```htmlembedded=
<input type="text" id="targetInput">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');

triggerBtn.addEventListener('click', function(){
    console.log(el.value);
    console.log(typeof(el.value));
})
```
如果在 input 輸入數字 123 以後點選「觸發按鈕」，可以在 console 中觀察到以下結果:

![](https://i.imgur.com/18bzrew.png)

**因此如果要對表單的「數值」進行運算，請記得要先使用 `parseInt` 做型別轉換。**

範例如下:
HTML
```htmlembedded=
<input type="text" id="targetInput">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');

triggerBtn.addEventListener('click', function(){
    let newValue = parseInt(el.value);
    console.log(newValue);
    console.log(typeof(newValue));
})
```
結果:

![](https://i.imgur.com/k18ol8z.png)



### `.value`, `.getAttribute('value')` 的差異

**以下觀念針對常用的「input」這個 HTML 標籤做說明:**



HTML
```htmlembedded=
<input type="text" id="targetInput" value="123">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');
console.log(`el.value: ${el.value}`);

triggerBtn.addEventListener('click', function(){
    el.value = "任意填入的值";
    console.log(`el.value: ${el.value}`);
})
```

同學的 console 結果應該會呈現如下:

![](https://i.imgur.com/HYHEDTk.png)


看到這邊，是不是認為 `<input type="text" id="targetInput" value="123">` 這行程式碼的 `value="123"` 應該已經被修改為 `value="任意填入的值"` 了? 

>不過，如果我們將程式碼修改如下，並一樣的點選「觸發按鈕」觀察結果:

HTML
```htmlembedded=
<input type="text" id="targetInput" value="123">
<button id="triggerBtn">觸發按鈕</button>
```
JS
```js=
let el = document.querySelector('#targetInput');
let triggerBtn = document.querySelector('#triggerBtn');

triggerBtn.addEventListener('click', function(){
    el.value = "任意填入的值";
    console.log(`el.value: ${el.value}`);
    console.log(`el.getAttribute('value'): ${el.getAttribute('value')}`);
})
```

可以發現網頁上 input 欄位「輸入的值」的確已經被更改為 "任意填入的值"

![](https://i.imgur.com/dI37ggU.png)

但是 `el.value` 與 `el.getAttribute('value')` 卻是不一樣的，呈現結果如下:

![](https://i.imgur.com/1RXP4aB.png)


### 由此可知，修改 `el.value` 不等於修改 HTML 標籤的 value 屬性值


* `el.value` 對應的是 input 欄位目前「輸入的值」
* `el.getAttribute('value')` 對應的是 input 欄位的「預設屬性值」
* 修改 `el.value` 並不會影響 input 標籤的 value 預設屬性，使用 `setAttribute()` 才會。

## axios 
### axios 的 get 語法可以用來取得遠端伺服器的資料

先在HTML載入axios 的 CDN
```htmlembedded=
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
```

```js=
// 在以下 URL 的部分填入 API 網址
axios.get('URL')
    // 如果連接成功，可以用 then() 處理傳回來的值，以下程式碼將回傳結果儲存於 responce。
  .then(function (response) {
    	console.log(response);
  });
```

### HTTP 狀態碼

使用 AJAX 比較常遇到、需要了解的狀態碼訊息:

1. **成功回應 (Successful responses, 200–299)**
這區間的狀態碼表示伺服器有成功接收到用戶端要求。以 AJAX 的串接為例，如果回傳的 **status 為 200**，則代表有成功接收到資料。

2. **用戶端錯誤 (Client errors, 400–499)**
這區間的狀態碼表示有錯誤發生，且錯誤來自於「用戶端」。以 AJAX 的串接為例，
    * 回傳的 **status 為 400**，表示遠端伺服器接收到無效語法、無法理解請求，因此需要檢查程式碼有無寫錯的地方。 
    * 回傳的 **status 為 403**, 表示禁止使用，這代表用戶端沒有訪問權限，因此沒辦法成功串接資料。 
    * 回傳的 **status 404**，表示找不到檔案資料。


3. **伺服器端錯誤 (Server errors, 500–599)**
如果發生狀態碼為 **5xx** 的錯誤，則表示錯誤發生跟「遠端伺服器」有關，此時就需要跟後端工程師進行協調了。

## 將物件包物件轉為陣列包物件小技巧
1. Object.values
```js=
const family = {
    liFamily:{
        name:'Jasper'
    },
    huangFamily:{
        name:'jeff'
    },
    changFamily:{
        name:'bear'
    }
}
console.log(Object.values(family))
// 帶出一筆陣列包三筆物件
取得的是family內的每筆物件的值,放入一個陣列內
```
呈現如下:
![](https://i.imgur.com/oC2uOYd.jpg)

```js=
// 搭配forEach
Object.values(family).forEach((item)=>{
console.log(item)  
//帶出三筆物件
取得的是family內的每筆物件屬性(不含屬性內的值),放入一個陣列內
})
```
呈現如下:
![](https://i.imgur.com/JbjPwtW.jpg)


2. Object.keys
```js=
const family = {
    liFamily:{
        name:'Jasper'
    },
    huangFamily:{
        name:'jeff'
    },
    changFamily:{
        name:'bear'
    }
}
console.log(Object.keys(family))
// 帶出的是family內的屬性
```
呈現如下:
![](https://i.imgur.com/jpiCQiD.jpg)

```js=
// 搭配forEach
Object.keys(family).forEach((key)=>{
console.log(family[key]) 
})
// 一樣可以取得每一筆物件
```
呈現如下:
![](https://i.imgur.com/pu3ULy8.jpg)


通常陣列包物件若要取的該陣列內包含幾筆物件,通常可以使用
```js=
const friends = [bear:{...},jasper:{...},jeff:{...}]

console.log(friends.length) // 3
```
若是在物件包物件的資料個是下該如何取得長度呢?
```js=
const family = {
    liFamily:{
        name:'Jasper'
    },
    huangFamily:{
        name:'jeff'
    },
    changFamily:{
        name:'bear'
    }
}
console.log(Object.values(family).length) // 3
console.log(Object.keys(family).length) // 3

```

---
## 如何使用axios撈取資料回來並渲染在畫面上
```htmlembedded=
<div class="container">
  <div class="row productList">
  </div>
</div>
```

```js=
// 綁定Dom元素
const productList = document.querySelector(".productList");

// 先宣告一個變數,待撈取資料後存入
let productsData;

// 撈取資料的function
function getProducts(){
// 取得資料的網址(通常事後端給的)
  let url = "https://livejs-api.hexschool.io/api/livejs/v1/customer/jasper0730/products";
axios.get(url)
// 若成功回傳跑then
  .then(function(res){
  // 資料存入先前準備好的變數內
  productsData = res.data.products;
  // 渲染到畫面上的function
  render(productsData);
})
// 若失敗回傳跑catch
.catch(function(error){
  console.log(error);
})
}

// 渲染到畫面上的function
function render(productsData){
  let str=""; // 先宣告一個變數待會拿來暫存資料
  用撈回的資料跑forEach,把每一筆物件存入str
  productsData.forEach(function(item){
    str += `<div class="col-6 mb-3">
      <div class="card">
        <img src="${item.images}" class="card-img-top productImg" alt="產品圖片">
        <div class="card-body">
          <h5 class="card-title"><strong>標題:</strong> ${item.title}</h5>
          <p class="card-text"><strong>種類:</strong> ${item.category}</p>
          <p class="card-text"><strong>原始價格:</strong> ${item.origin_price}</p>
          <p class="card-text"><strong>售價:</strong> ${item.price}</p>
          <p class="card-text"><strong>描述:</strong> ${item.descrption}</p>
        </div>
      </div>
    </div>`
  })
  // 先前綁好的Dom元素用innHTML帶入str渲染到畫面上
  productList.innerHTML = str
}
// 執行getProducts函式
getProducts();
```


---
## 如何將字串反轉
ex:柏斯賈是我 轉成 我是賈斯柏

範例程式碼如下:
```js=
let name = '柏斯賈是我'

let reverseName = name.split('').reverse.join('');

console.log('name') // 柏斯賈是我
console.log('reverseName') // 我是賈斯柏
```
