_ 占位符

 你問到了一個在現代 JavaScript 中非常常見且實用的語法習慣!

簡單的答案是:_ (底線) 在這裡是一個「佔位符」,用來告訴閱讀程式碼的人(以及程式碼檢查工具):「我在這裡需要一個參數,但我完全不會用到它,所以我就忽略它了。」


詳細解釋

讓我們來分解 Array.from({ length: 24 }, (_, i) => { ... }) 這段程式碼:

  1. Array.from(arrayLike, mapFn):

    • Array.from 是一個靜態方法,可以用來從一個「類陣列物件」(array-like object) 或「可迭代物件」(iterable object) 創建一個新的、真正的陣列。

    • 它接受第二個可選參數 mapFn,這是一個映射函式 (map function)。Array.from 會對創建的新陣列中的每一個元素都執行一次這個函式,並用函式的回傳值來替換該元素。

  2. { length: 24 }:

    • 這是一個「類陣列物件」。它不是一個真正的陣列,但它有一個 length 屬性,所以 Array.from 知道要創建一個包含 24 個元素的陣列。

    • 在這一刻,這個新創建的陣列是 [undefined, undefined, ..., undefined] (總共 24 個)。

  3. (_, i) => ${String(i).padStart(2, '0')}:00``:

    • 這就是那個 mapFn 映射函式。Array.from 在遍歷那個長度為 24 的新陣列時,會為每個位置呼叫這個函式。

    • 這個映射函式會接收兩個參數

      • 第一個參數:是陣列中當前元素的值。因為我們的陣列是 [undefined, undefined, ...],所以這個參數永遠都是 undefined

      • 第二個參數:是陣列中當前元素的索引 (index),從 023

這就是 _ 出場的地方:

  • 我們在程式碼邏輯中,只需要用到第二個參數 i (索引),來產生 '00:00', '01:00', '02:00'... 這樣的字串。

  • 我們完全不需要用到第一個參數(那個永遠是 undefined 的值)。

為了讓程式碼更清晰,我們不使用像 (value, i)(element, i) 這樣有意義的名稱來命名第一個參數,因為那會誤導讀者,讓他們以為 value 是有用的。

所以,我們用一個單獨的底線 _ 來作為第一個參數的名稱。這在 JavaScript (以及 Python, Ruby 等許多其他語言) 的社群中,已經成為一個廣泛接受的慣例,它的意思就是**「我宣告了這個參數,但我故意不用它」**。


其他範例

這個慣例在很多地方都很有用。

範例 1:在 .forEach
如果你只想用索引,而不在乎元素本身。

const myArray = ['a', 'b', 'c'];
myArray.forEach((_, index) => {
    console.log(`第 ${index + 1} 個項目`);
});
  

範例 2:在 Promise 的 .then
如果你只關心 Promise 完成了,而不在乎它回傳的具體結果。

fetchSomeData().then(_ => {
    // 我不在乎 fetchSomeData 回傳了什麼,
    // 我只想在它完成後執行這段程式碼。
    showLoadingSpinner = false; 
});
  

範例 3:在解構賦值中
如果你想跳過陣列中的某些元素。

const coordinates = [10, 20, 30];
const [x, _, z] = coordinates; // 我只想要 x 和 z,忽略掉 y

console.log(x); // 10
console.log(z); // 30
  

總之,_ 是一個非常有用的程式碼可讀性工具,它能讓你的意圖更清晰。

留言

這個網誌中的熱門文章

Offscreen Canvas

外部網頁新增 Google 日曆行程(URL模板)

計算 Canvas 文字最大字體