線上課程觀課進度管理小工具開發日誌
Day 6:JavaScript 程式碼執行排序:遞迴函數、Call Stack、Task Queue
Call Stack;遞迴函數與 call stack 的關係;Task Queue(非同步的概念再釐清)
Day 9:「修煉圈圈 Practice Rings」Web app 開發日誌 - 2025 六角 AI Vibe Coding 體驗營期末大魔王作業
這份筆記旨在記錄 2025 六角 Vibe Coding 體驗營每日作業 Day 21 的期末專案成果,從一個簡單的個人痛點出發,透過與 AI(在我這個情境中是 Perplexity)協作,在一天內完成了一個包含前後端的全端網頁小工具:「修煉圈圈 Practice Rings」。
<100 subscribers
線上課程觀課進度管理小工具開發日誌
Day 6:JavaScript 程式碼執行排序:遞迴函數、Call Stack、Task Queue
Call Stack;遞迴函數與 call stack 的關係;Task Queue(非同步的概念再釐清)
Day 9:「修煉圈圈 Practice Rings」Web app 開發日誌 - 2025 六角 AI Vibe Coding 體驗營期末大魔王作業
這份筆記旨在記錄 2025 六角 Vibe Coding 體驗營每日作業 Day 21 的期末專案成果,從一個簡單的個人痛點出發,透過與 AI(在我這個情境中是 Perplexity)協作,在一天內完成了一個包含前後端的全端網頁小工具:「修煉圈圈 Practice Rings」。
arr.reduce:陣列加總 => Day 1-3
arr.map:陣列映射 => Day 1-3
const arr = Array(length).fill(0):建立長度 length 的全零陣列
arr.join($string):把陣列所有元素合併成一個字串,元素中都插入字串 string(預設值為,,可使用空字串)
原來我練習寫的參數化測試方法是 test.each 使用了 table-driven test:
把不同的參數代入同一個 function 測試得到各自的預期結果
在 JavaScript 中,表格會以 array 呈現,test.each 按照 array element 相對位置存取
參考資料來源:
可以引用與呼叫自身的函數。適合用來以堆疊重複形態的方式將一個大問題拆解成基本形態 base case 和最終通式形態 recursive case,逐層往下執行後再逐層組回來。
目前理解:
如果是線性多項式的形態,可以想成是定義第一項和通式之後,從第 n 項逐漸往前列出每一項數值,再從頭疊加回來。
參考資料來源:
本質上是「先建立完整列表,再對列表做處理」:
先算出總共有幾項,建一個固定長度的陣列 arrTemp。
用 for 迴圈算出每一項元素的字串填進陣列。
用 map 把這個陣列「轉成另一種陣列 arrNumber」(字串 → 數值),可能會用到字串方法如:split。
用 reduce 把整個數值陣列 arrNumber 「摺成一個總和」。
關鍵特徵是:
一開始就「知道要幾項」,所以適合用陣列表示。
把問題想成「一個完整的序列」:
第 1 項、第 2 項、…、第 n 項,全部先算出來。
完全沒有函式呼叫自己,所以不是遞迴,而是典型「陣列 + 迴圈 + 陣列方法」寫法。
這種寫法的優點:
很貼合 JS 陣列 API 的原生用途:map 做轉換、reduce 做累積,對前端工程師來說很好讀。
容易加上額外處理,例如之後要 filter 某些項目,或改變每一項的格式,直接插一個 map / filter 就好。
不會有遞迴深度問題,也比較直觀看出複雜度是「跟陣列長度成正比」。
不再從「整個陣列」出發,而是從「問題本身」出發:
要算到第 n 項,可以拆成「先算到第 (n−1) 項,再加上第 n 項的通式形態」。
定義一個遞迴關係:
Base case:第一項。
Recursive case:從第 n 項往回看
先取得「到第 (n-1) 項的算式與總和。」
再加上第 n 項的字串和數值到算式字串與總和上。
特徵:
沒有先建一個完整的陣列,而是「一次處理一項」,靠「函式回傳值」一層一層往外累積。
主要在運用 call stack 的特性:
先往內呼叫到最小的 n(類似 MDN 文件示範的 begin 段)。
再一路往外 return 把算式和總和疊回來(類似 MDN 文件示範的 end 段)。
這種寫法的優點:
在沒有「很明顯的陣列結構」時,遞迴有時會比強行用 for + index 更清楚(例如樹狀結構、巢狀物件)。
缺點(在線性數列的練習題上):
比陣列 + 迴圈的成本高,寫起來也稍微難懂(尤其是剛學遞迴時)。
對於很大的 n,會有呼叫深度與堆疊的開銷問題(理論上有 stack overflow 風險,雖然這題規模不大時還好)。
目前可以先這樣判斷:
for / while 迴圈
或 Array(length).fill().map().reduce() 會更貼近 JS 陣列本來設計的使用方式,也比較符合前端日常實務。
樹狀結構(DOM 樹、目錄樹)。
巢狀資料(巢狀物件、JSON)。
目前練習還沒碰到這些資料結構
兩個的作用域都只在區塊內
從記憶體與變數綁定(binding)的角度,可以這樣理解:
const
宣告後會建立「不可重新賦值的變數綁定」,也就是這個變數一旦被賦予某個值,就不能再用 = 把它改成另一個值。
如果綁定的值是物件或陣列,那個值本身是一個「參考(reference)」,指向堆積區中的某個實體;const 不能改變這個參考本身(不能讓變數去指向另一個物件),但可以透過這個參考去修改物件的屬性或陣列元素。
因此,const 很適合用來宣告:
不會被重新賦值的原始型別(例如計算完的 length)。
不會被整個換掉的物件/陣列(例如 arrTemp),雖然裡面的內容會變動。
let
同樣是區塊作用域(block scope),但允許之後多次重新賦值,也就是可以用 = 改變變數目前綁定的是哪一個值。
如果綁定的是物件或陣列,就可以讓這個變數改指向另一個物件或另一個陣列。
典型使用情境是「會隨流程改變的值」,例如迴圈計數器 for (let i = 0; i < length; i += 1)。
可以用一個比喻來記:
const 固定的是「這條變數線連到哪一個盒子」,盒子裡的東西可以換。
let 則是連到哪個盒子、要不要換一個新盒子,都可以在之後重新指定。
參考資料來源:
pnpm add -D eslint@^8.57.0 eslint-config-airbnb-base eslint-plugin-import
Airbnb 官方指南有明確寫:
Use const for all of your references; avoid using var. eslint: prefer-const, no-const-assign.
arr.reduce:陣列加總 => Day 1-3
arr.map:陣列映射 => Day 1-3
const arr = Array(length).fill(0):建立長度 length 的全零陣列
arr.join($string):把陣列所有元素合併成一個字串,元素中都插入字串 string(預設值為,,可使用空字串)
原來我練習寫的參數化測試方法是 test.each 使用了 table-driven test:
把不同的參數代入同一個 function 測試得到各自的預期結果
在 JavaScript 中,表格會以 array 呈現,test.each 按照 array element 相對位置存取
參考資料來源:
可以引用與呼叫自身的函數。適合用來以堆疊重複形態的方式將一個大問題拆解成基本形態 base case 和最終通式形態 recursive case,逐層往下執行後再逐層組回來。
目前理解:
如果是線性多項式的形態,可以想成是定義第一項和通式之後,從第 n 項逐漸往前列出每一項數值,再從頭疊加回來。
參考資料來源:
本質上是「先建立完整列表,再對列表做處理」:
先算出總共有幾項,建一個固定長度的陣列 arrTemp。
用 for 迴圈算出每一項元素的字串填進陣列。
用 map 把這個陣列「轉成另一種陣列 arrNumber」(字串 → 數值),可能會用到字串方法如:split。
用 reduce 把整個數值陣列 arrNumber 「摺成一個總和」。
關鍵特徵是:
一開始就「知道要幾項」,所以適合用陣列表示。
把問題想成「一個完整的序列」:
第 1 項、第 2 項、…、第 n 項,全部先算出來。
完全沒有函式呼叫自己,所以不是遞迴,而是典型「陣列 + 迴圈 + 陣列方法」寫法。
這種寫法的優點:
很貼合 JS 陣列 API 的原生用途:map 做轉換、reduce 做累積,對前端工程師來說很好讀。
容易加上額外處理,例如之後要 filter 某些項目,或改變每一項的格式,直接插一個 map / filter 就好。
不會有遞迴深度問題,也比較直觀看出複雜度是「跟陣列長度成正比」。
不再從「整個陣列」出發,而是從「問題本身」出發:
要算到第 n 項,可以拆成「先算到第 (n−1) 項,再加上第 n 項的通式形態」。
定義一個遞迴關係:
Base case:第一項。
Recursive case:從第 n 項往回看
先取得「到第 (n-1) 項的算式與總和。」
再加上第 n 項的字串和數值到算式字串與總和上。
特徵:
沒有先建一個完整的陣列,而是「一次處理一項」,靠「函式回傳值」一層一層往外累積。
主要在運用 call stack 的特性:
先往內呼叫到最小的 n(類似 MDN 文件示範的 begin 段)。
再一路往外 return 把算式和總和疊回來(類似 MDN 文件示範的 end 段)。
這種寫法的優點:
在沒有「很明顯的陣列結構」時,遞迴有時會比強行用 for + index 更清楚(例如樹狀結構、巢狀物件)。
缺點(在線性數列的練習題上):
比陣列 + 迴圈的成本高,寫起來也稍微難懂(尤其是剛學遞迴時)。
對於很大的 n,會有呼叫深度與堆疊的開銷問題(理論上有 stack overflow 風險,雖然這題規模不大時還好)。
目前可以先這樣判斷:
for / while 迴圈
或 Array(length).fill().map().reduce() 會更貼近 JS 陣列本來設計的使用方式,也比較符合前端日常實務。
樹狀結構(DOM 樹、目錄樹)。
巢狀資料(巢狀物件、JSON)。
目前練習還沒碰到這些資料結構
兩個的作用域都只在區塊內
從記憶體與變數綁定(binding)的角度,可以這樣理解:
const
宣告後會建立「不可重新賦值的變數綁定」,也就是這個變數一旦被賦予某個值,就不能再用 = 把它改成另一個值。
如果綁定的值是物件或陣列,那個值本身是一個「參考(reference)」,指向堆積區中的某個實體;const 不能改變這個參考本身(不能讓變數去指向另一個物件),但可以透過這個參考去修改物件的屬性或陣列元素。
因此,const 很適合用來宣告:
不會被重新賦值的原始型別(例如計算完的 length)。
不會被整個換掉的物件/陣列(例如 arrTemp),雖然裡面的內容會變動。
let
同樣是區塊作用域(block scope),但允許之後多次重新賦值,也就是可以用 = 改變變數目前綁定的是哪一個值。
如果綁定的是物件或陣列,就可以讓這個變數改指向另一個物件或另一個陣列。
典型使用情境是「會隨流程改變的值」,例如迴圈計數器 for (let i = 0; i < length; i += 1)。
可以用一個比喻來記:
const 固定的是「這條變數線連到哪一個盒子」,盒子裡的東西可以換。
let 則是連到哪個盒子、要不要換一個新盒子,都可以在之後重新指定。
參考資料來源:
pnpm add -D eslint@^8.57.0 eslint-config-airbnb-base eslint-plugin-import
Airbnb 官方指南有明確寫:
Use const for all of your references; avoid using var. eslint: prefer-const, no-const-assign.
Share Dialog
Share Dialog
No comments yet