---
tags: JS 直播班 - 2021 春季班
---
# 4/2 線上 Slack 助教
## 今日輪班助教時間
暄雯:4/2(五)
早上 9:00 - 早上 11:00,下午 1:30 - 下午 5:30
## 發問規範
老師助教同學們好,**這是我的 Codepen**,我**原本預期**「JS 第 8 行會出現數字 8」,**但卻出現**「預期外的結果是 0」,想問下問題出在哪裡?
## 注意
1. 請各位先到 Slack 上將問題放在助教服務內的 thread,如圖

2. 遵循以上的發問規範以便助教查看問題,不可直接貼上網址而沒有說明文字或者只提供截圖
3. 助教會依照 Slack 上的順序回覆問題
4. 以下問題區塊只能由助教自行增加
5. 助教會將回覆寫在下方問題區塊
## 問題
1. **穎旻:**
老師助教同學們好,這是我的 [Codepen](https://),我原本預期「JS 第 8 行會出現數字 8」,但卻出現「預期外的結果是 0」,想問下問題出在哪裡?
> 助教回覆:
---
2. **tim:**
助教好,這是我的 Codepen
https://codepen.io/tim-chou/pen/ExZWbqb?editors=1010
在 js 第 87 到 101 行,練習加入購物車的 api 時,
發現當我第一次點擊加入購物車時,
可以順利加入購物車,
但同個品項點擊第二次時,會沒反應,
要點擊第三次,才會渲染上一次的結果
再麻煩助教解答,感謝
> 助教回覆:
目前檢視是 API 的問題,工程師已經修好哩,同學可以再試看看~
---
3. **leolee:**
助教好,這是我的 [Codepen](https://codepen.io/nekorice/pen/wvgJPLw)
我不清楚 sort() 具體的運作方式,sort 部分的 code 是參考其他同學的寫法,google 也找不太到關鍵字...
想請教在 js 22 ~ 28 行
sort() 具體來說做了些什麼事情
他改變了原本 groupData 的內容嗎
為什麼會需要再定義一個 sortData = [] 的陣列呢?
這部份真的上網怎麼找也找不到資源...
希望能得到觀念清晰的解釋
非常感謝 :pray:
> 助教回覆:
> 這邊先給予一個簡單範例,接下會以這個範例來講解:
```
const num = [30, 14, 15, 22]
num.sort(function(a, b){
console.log(a, b)
return a - b // 結果會為正數或負數
})
console.log(num) // sort 執行完後,num 結果為 [14,15,22,30]
```
>目前你的想法是正確的哩,sort 會改變原本 groupData 的內容。
一開始 sort 會從陣列中挑選兩個數字(a, b)來比對。比對完後,將這兩個數字進行排序。排序完,再從這兩個數字中選擇最大的數字與陣列中下個數字來繼續比對……
這邊的 return 就是用來回傳比對的結果哩
>
>如果 return 的結果為正數,則代表 a 大於 b,則排序結果變為:[b, a];相反的,如果結果為負數,代表 a 小於 b,排序結果會變為:[a, b]。
>
>以範例來講,它會先比對 30 跟 14,return 得到的結果為正數,因此第一次執行完,陣列的排序為:[14, 30, 15, 22]
>
>第二次則是以 30 跟 15 做比較,因為 return 結果為正數,所以 15 的排序往前。這時,因為前面還有數字,所以 15 會繼續跟前面的數字比對,直到比對結果為負數,則停止比較與排序。
>
>return 的方式其實有很多種,不一定要使用 a - b 的方式。用三元運算子、if else 也是 OK 的,只要能夠讓程式判斷他們的大小即可。
>
>另外,這邊有沒有宣告 sortData 陣列都可以哩,直接執行 groupData.sort() 也沒有問題哦。宣告 sortData 變數只是將經過排序的資料儲存起來,之後在做整理或是使用時會比較方便。
>
>
>這邊補充幾篇文章給你參考,裡面有不同的範例,同學可以試著去理解看看。也建議同學,可以試著自己定義不同的資料內容,練習操作幾次,這樣會更容易理解跟吸收哩:
>* [關於 Array.prototype.sort() 排序這件不小的小事](https://hsiangfeng.github.io/javascript/20190426/1966510488/)
>* [JavaScript Array sort() (陣列排序)](https://www.fooish.com/javascript/array/sort.html)
>* [淺談 JS sort() 到背後排序方法](https://medium.com/@leokao0726/%E6%B7%BA%E8%AB%87-js-sort-%E5%88%B0%E8%83%8C%E5%BE%8C%E6%8E%92%E5%BA%8F%E6%96%B9%E6%B3%95-1035f5b8cde8)
---
4. **Hsin:**
助教好,先附上 [codepen](https://codepen.io/hsinhui/pen/OJWWrzX?editors=1011),這是我練習的 todolist,想多增加一個功能是 checkbox 打勾後將文字新增刪除線,於是在上網搜尋後發現可用 checkbox.checked == true 來操控,但在 52 行開始的程式碼卻無法正常運作,第二筆資料開始就會壞掉,還請助教幫忙解惑,感謝!
> 助教回覆:
> 這邊檢視資料新增刪除或是打勾,運作都沒有問題哩,第二筆資料也可以正常運作。
> 目前因為一開始畫面上並沒有 .done 這個 DOM,因此 checkbox 是沒有被賦予值的。新增資料後,checkbox 也沒有被重新賦予值,所以 forEach 無法運作哩
> 建議可以改為宣告一開始畫面就存在的 DOM 為變數,例如 .list,再用範圍取值的方式,來確認點擊的目標是否正確,如果正確就可以執行想要的程式。
> 範圍取值可以參考教學影片內容:[範圍內容取值](https://courses.hexschool.com/courses/1289881/lectures/31463151)
---
5. **Lita:**
助教好,這是我的 [CodePen](https://codepen.io/lita030/pen/gOgMGoE?editors=0010),
我在做主線 6 時沿用主線 5 的 lv3,做完後原本的篩選搜尋功能「JS 95 - 100」,卻不能篩選了,想問下問題出在哪裡?
> 助教回覆:
> 這邊檢視你的程式碼,篩選功能是在第 112 - 115 行。
如果要詢問新增的功能無法執行的原因,第 107 行執行的 render(),JS 中並沒有宣告這個函數哦。可以改為 renderData() 來讓程式能正確執行。
如果是詢問篩選的功能,第 114 行執行的 render(searchOption.value),也要修改為 renderData()。修改後,renderData() 需要增加判斷 data 的 area 是否與 value 的值相等,將資料篩選出來哩。
目前執行 renderData(),不會經過任何判斷,而是直接將 data 的資料全部印出來。
---
6. **圈圈:**
助教好,這是我的 [codepen](https://codepen.io/wei-the-lessful/pen/XWppQoy?editors=0012)。我想監聽加入購物車的按鈕(第 12 行),但第 2 行的宣告只能抓到空值,導致無法監聽。
現在想到的作法,是在外面宣告一個陣列(第 1 行),在 productData.forEach 把抓到的元素推進陣列再加上監聽。但我發現這樣監聽一樣必須擺在 function init 中,感覺邏輯被用得太複雜。
像這種需要等 axios 渲染完畫面再執行監聽的例子,有沒有能直接在外面用 document.querySelector 取到 dom 元素的方法?
> 助教回覆:
> 按鈕的部分可以嘗試再增加一些不同的設定,例如:dataset、class
監聽加入購物車的按鈕可以改為監聽 productList 是否被點擊,假如被點擊則判斷 e.target 相關的值是否為「加入購物車」按紐。例如:e.target.dataset、e.target.nodeName
這樣就不需要將監聽放在 axios 裡了~
---
7. **Shino:**
助教、老師好,這是我第七關主線任務的 [Codepen 連結](https://codepen.io/shiiinnooo/pen/dyNNBme?editors=0010),
想請問一下為什麼「totalObj 和 newData 放在 JS 第 9、10 行宣告,下方兩個函式就吃不到」,放在第 3、4 行宣告才可以呢?
```
let totalObj = {};
let newData = [];
selectArea();
renderC3();
```
我的認知是放在第 9、10 行宣告和下方兩個函式是在同一個作用域,想請問一下觀念哪裡出問題了,謝謝。
> 助教回覆:
> 不同函式的作用域都是不一樣的。
function 中的變數都屬於區域變數的作用範圍,不會被其他函式所用。
所以在 A 函式裡宣告的變數並不會給 B 函式或其他函式使用,如果在其他函式要調用 A 函式的變數,通常會以參數的方式來傳入哩
---
8. **Aasta Chen:**
助教、老師好
我想請問一下在 forEach 題型練習這個章節裡,為什麼要做網頁初始化狀態呢?謝謝
> 助教回覆:
不曉得你詢問的是 forEach 題型練習章節的 [搭配網頁初始化狀態](https://courses.hexschool.com/courses/2020111/lectures/30847748) 單元嗎?
如果是指這個單元提到的網頁初始化狀態,主要是跟同學講解 forEach 也可以用在網頁初始化。
通常我們拿到的資料,會有很多筆內容,如果我們希望使用者一點進來網頁就可以看到這些資訊,就會需要對網頁做初始狀態,將資料全部渲染到網頁上。
這時,就需要結合 forEach 來渲染資料哩~
---
9. **Carrie:**
老師助教同學們好,這是我的 [CodePen](https://codepen.io/echocarriet/pen/poRPPgp)
在練習助教直播的驗證表單套件 ( validate.js ),成功的把未符合規則的欄位中顯示訊息。
但遇到欄位未填寫正確,點選 " 新增套票 " 按鈕還是可以把資料新增到下方票券中。
想請問該怎麼在表單未填寫正確下,終止新套票到下方清單中呢 ? 謝謝 !
( 有嘗試在 line88 addTicket() 做一些設定讓 line168 renderValidate() 在未符合驗證規則時不要新增資料到票券中,但越寫越髒到不知道自己在做甚麼了:sob: )
> 助教回覆:
可以嘗試修改執行的順序。在 addTicketBtn 監聽事件裡先執行驗證的函式:renderValidate(),若驗證成功才會執行 addTicket()。
另外,目前測試如果完全沒有輸入資料,點擊「新增套票」時,不會出現驗證內容,需要先輸入一個欄位的資料,其他欄位才會跳出訊息。renderValidate() 的程式可以嘗試修正。
---
(這裡只能由助教自行增加問題,請大家將問題放在 thread 上)