# Day 5 陣列基本方法;遞迴函數;const/let 宣告的差異 **Published by:** [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake/) **Published on:** 2025-11-26 **URL:** https://paragraph.com/@gcake/day-5 ## Content 陣列基本方法arr.reduce:陣列加總 => Day 1-3arr.map:陣列映射 => Day 1-3const arr = Array(length).fill(0):建立長度 length 的全零陣列arr.join($string):把陣列所有元素合併成一個字串,元素中都插入字串 string(預設值為,,可使用空字串)table-driven test原來我練習寫的參數化測試方法是 test.each 使用了 table-driven test: 把不同的參數代入同一個 function 測試得到各自的預期結果 在 JavaScript 中,表格會以 array 呈現,test.each 按照 array element 相對位置存取 參考資料來源:An introduction to table driven tests in VitestArray.prototype.map() - JavaScript - MDN Web DocsArray.prototype.reduce() - JavaScript - MDN Web DocsArray.prototype.join() - JavaScript - MDN Web DocsArray - JavaScript - MDN Web Docs遞迴函數可以引用與呼叫自身的函數。適合用來以堆疊重複形態的方式將一個大問題拆解成基本形態 base case 和最終通式形態 recursive case,逐層往下執行後再逐層組回來。 目前理解: 如果是線性多項式的形態,可以想成是定義第一項和通式之後,從第 n 項逐漸往前列出每一項數值,再從頭疊加回來。 參考資料來源:Recursion - Glossary - MDN Web DocsCall stack - Glossary - MDN Web Docs線性資料以純陣列方法與遞迴函數的解題思維不同純陣列版本在想什麼本質上是「先建立完整列表,再對列表做處理」:先算出總共有幾項,建一個固定長度的陣列 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)。目前練習還沒碰到這些資料結構const/let 宣告的差異兩個的作用域都只在區塊內JavaScript 中 const 與 let 的差異(記憶體角度)從記憶體與變數綁定(binding)的角度,可以這樣理解:const宣告後會建立「不可重新賦值的變數綁定」,也就是這個變數一旦被賦予某個值,就不能再用 = 把它改成另一個值。如果綁定的值是物件或陣列,那個值本身是一個「參考(reference)」,指向堆積區中的某個實體;const 不能改變這個參考本身(不能讓變數去指向另一個物件),但可以透過這個參考去修改物件的屬性或陣列元素。因此,const 很適合用來宣告:不會被重新賦值的原始型別(例如計算完的 length)。不會被整個換掉的物件/陣列(例如 arrTemp),雖然裡面的內容會變動。let同樣是區塊作用域(block scope),但允許之後多次重新賦值,也就是可以用 = 改變變數目前綁定的是哪一個值。如果綁定的是物件或陣列,就可以讓這個變數改指向另一個物件或另一個陣列。典型使用情境是「會隨流程改變的值」,例如迴圈計數器 for (let i = 0; i < length; i += 1)。可以用一個比喻來記:const 固定的是「這條變數線連到哪一個盒子」,盒子裡的東西可以換。let 則是連到哪個盒子、要不要換一個新盒子,都可以在之後重新指定。參考資料來源:const - JavaScript - MDN Web Docslet - JavaScript - MDN Web Docs語法與型別 - JavaScript - MDN Web Docs記憶體管理 - JavaScript - MDN Web Docs導入 airbnb JavaScript 寫作規範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.Airbnb JavaScript Style Guide() {GitHub - Airbnb//javascriptAirbnb JavaScript 寫作規範(中文版)Airbnb CSS 寫作規範(中文版)prefer-const - ESLintno-var - ESLint ## Publication Information - [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake/): Publication homepage - [All Posts](https://paragraph.com/@gcake/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@gcake): Subscribe to updates