JavaScript 函數參數為什麼用 _?這樣寫有什麼意義?
更新日期: 2025 年 5 月 3 日
你可能在程碼中看過這樣的寫法…
array.map((_, index) => {
console.log(index);
});
初學者可能會疑惑:「這個底線 _
是什麼意思?它是特殊符號嗎?它是不是語法的一部分?能不能換成別的?」
這篇文章會從基礎開始,帶你了解:
function(_, __)
這種寫法代表什麼?- 什麼時候我們會使用
_
作為函數參數? - 有沒有需要注意的地方?
- 這個慣例對寫程式有什麼好處?
底線 _
在 JavaScript 中是什麼?
首先你要知道的是:在 JavaScript 中,底線(_
)並不是特殊符號,也不是語言保留字。
它只是一個普通的變數名稱,你完全可以把它當作 x
、foo
、a
等一般變數來看待。以下兩個函式其實是一樣的:
function example(a) { }
function example(_) { }
也就是說:你可以把底線當作任意變數名稱使用,它本身不會影響程式行為。
為什麼會用 _
代表「忽略這個參數」?
在 JavaScript 中,使用底線(_
)作為函數參數名稱來表示「這個參數我知道它存在,但我不打算使用」是一種程式設計慣例(convention),而不是語言層級的強制規則。
這種做法之所以流行,是因為它在可讀性與語意表達上非常直覺,能讓程式碼的意圖變得更加明確。
寫法背後的語意設計
當你在撰寫函式時,有時候會遇到這樣的情況:
- 函式會自動收到多個參數(例如事件處理器、Array 的
map
/filter
/forEach
等回呼函式) - 但你只對其中一部分參數有興趣
- 為了維持參數結構與語法正確性,仍然要保留那些「不會被用到的參數」
這時,就可以使用 _
來取代那些明知不會使用,但仍需要寫下來的參數位子。
例如:
array.map((_, index) => {
// 我只想用 index,不使用元素本身
console.log(index);
});
這裡的 _
並不是什麼特殊符號,它本質上是一個合法的變數名稱。
但在開發慣例中,它具有「我知道這個值存在,但我選擇忽略它」的語意。
這樣做的好處
這種用法雖然簡單,卻具有不少實際效益,尤其是以下兩點最為明顯:
1. 提升可讀性與語意清晰度
使用 _
能夠立即讓其他開發者知道:你不是忘了用這個參數,而是你「有意」不使用它。
這對於維護程式碼的團隊合作來說,是一種良好的溝通方式。
如果你取名為 unusedValue
、temp1
、xyz
,讀者反而不容易判斷你的意圖。
但當你看到 _
時,大多數開發者都會理解這是「佔位用,不處理」。
2. 保留參數位置,維持函式結構完整
有些函式(尤其是回呼函式)會固定傳入特定數量與順序的參數,如果你完全不寫前面的參數,會導致你無法正確拿到後面想要的值。
✅ 舉例:
array.forEach((_, index, arr) => {
// 只想用 index 和原始陣列 arr,不需要元素值
});
如果你省略了 _
,就得不到正確的 index
,因為參數是依位置對應的。
這也是為什麼保留 _
能夠讓「函式簽名保持清楚」,並且避免潛在的錯誤或誤解。
額外補充:這也是對工具友好的寫法
像 ESLint 這種靜態檢查工具,通常會針對「定義了但未使用的參數」提出警告。
而在很多設定中,如果變數名稱是 _
,它就會被自動視為「有意忽略」,不會噴錯:
// .eslintrc 設定範例
{
"rules": {
"no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }]
}
}
因此這種寫法也間接成為與工具鏈兼容的最佳實務之一。
常見使用情境:為什麼要用 _
來忽略參數?
使用 _
作為函式參數或解構賦值時的佔位符,背後目的都是為了提升語意清晰度與程式結構完整性。
以下是三種實務開發中最常出現的場景說明:
陣列迴圈中只用到 index
或 key
許多陣列方法(如 map
、forEach
、filter
)的 callback function 會提供多個參數,一般順序是:
(value, index, array)
但有時你只對 index
感興趣,不需要使用 value
(元素本身)。
此時若省略第一個參數,index
就會對不到位置;所以我們保留第一個參數但用 _
命名,來表達「我知道它存在但不會用」。
範例:
const fruits = ['apple', 'banana', 'cherry'];
fruits.map((_, index) => {
console.log(`水果 ${index + 1}`);
});
好處說明:
- 避免破壞參數順序對應(不能只寫
(index)
,會錯位) - 強化語意:
_
直接傳達「不使用元素值」 - 降低維護成本:之後若要改用元素值,直接把
_
換掉即可
延伸補充:
這種寫法也常見於用 Object.entries()
做物件迴圈時:
Object.entries(userData).forEach(([_, value]) => {
console.log(value);
});
保留後面參數,忽略前面不重要的
某些回呼函式會傳入許多參數,但實際上我們只需要後面幾個,例如事件處理器、錯誤回呼、資料操作函式等。
如果直接省略前面參數,會導致你拿不到後面重要的值,所以這時可用 _
、__
依序佔位。
範例:
function handleEvent(_, __, detail) {
console.log('事件細節:', detail);
}
這裡假設某個函式呼叫時傳入三個參數,但我們只對 detail
感興趣,於是用 _
和 __
把前兩個位置保住。
常見使用場景:
- Express 路由中的 middleware handler
- 某些 UI 框架中的事件回傳(例如拖曳元件:
(event, ui, data)
) - Firebase 或其他 SDK 的 callback 函式
好處說明:
- 保持參數順序,避免錯誤使用
- 語意清晰,維護者一眼可見你真正關心的是哪個參數
解構賦值中只取部分值
當你從陣列中取值時,不一定每個值都要用上。如果你只想取第 3 個元素,前面兩個可以用 _
、__
作為佔位符。
範例:
const [_, __, thirdValue] = ['a', 'b', 'c'];
console.log(thirdValue); // "c"
這裡 _
和 __
的目的不是要使用,而是佔住位置,讓 thirdValue
能正確對應到第 3 項。
類似應用:
- 在使用
useState
的回傳時只想取 setter:
const [_, setCount] = useState(0);
- 在資料處理中跳過不重要的欄位:
const [_, importantValue] = getDataTuple(); // 只關心第二個回傳值
注意事項:
- 不建議重複使用
_
當變數名太多次(例如const [_, _, _, _, myValue]
),會讓除錯與意圖不明。 - 若只需保留部分,可改用逗號佔位語法(例如
const [,, third]
)來省略變數名。
注意事項與最佳實務
雖然在函式參數中使用 _
是一種被廣泛接受的慣例,但它畢竟只是變數命名方式的一種,並非語言的內建功能。
如果使用不當,反而可能造成閱讀上的困擾或程式邏輯錯誤。因此,以下幾點是你在使用 _
時應該注意的:
_
不是語法糖
在 JavaScript 中,_
並不是有特殊功能的「語法糖」(syntactic sugar),它和其他變數名稱完全一樣。
它不會被 JavaScript 當作「特殊保留變數」處理,因此你也可以為 _
賦值、操作、傳遞。
這意味著你必須小心不要誤以為它自動「忽略」了某些東西——你忽略它,是因為你選擇不使用它。
請勿過度濫用
雖然 _
能有效提升語意清晰度,但若在同一個函式中使用太多 _
、__
、___
作為佔位符,會讓程式難以維護與除錯。
例如:(_, __, ___, ____, importantValue)
的意圖就會變得模糊且難以追蹤來源。
最佳實務是:最多只使用一個 _
,其餘若不使用建議直接省略或用明確命名(如 unused
)。
命名應清楚傳達用途
若你在 callback 中使用第二個參數(如 index
),應該直接寫出變數名稱:(_, index)
,這比 (_, __)
更清楚。
這樣即便別人沒讀過這個函式,也能從變數名稱推測你的意圖。
例如:在 .map()
中看到 (_, index)
就能馬上明白「你只想處理 index,不使用元素值」。
不應重複定義 _
在同一個區域(scope)中,若你重複定義 _
,會造成先前定義被覆蓋。
例如在多層 callback 或解構中使用 _
,容易意外產生變數衝突或錯誤覆蓋。
解法是:限制 _
使用範圍在單一函式參數中,避免用 _
作為可變值或傳遞對象。
補充建議:
- 若你使用的是 TypeScript,可以使用
_param: unknown
的方式更明確地表示「不使用但仍保留類型」 - 若有多個不使用的參數且都需要保留,考慮用具語意的命名如
unusedError
、ignoredValue
總結:為什麼這種寫法值得學會?
在撰寫現代 JavaScript(或 TypeScript)應用程式時,_
作為函式參數的佔位符是一種簡潔又具語意的寫法。
儘管它不是語言內建機制,但因為符合「程式易讀性」、「語意明確性」、「工具相容性」等多重優點,已經成為業界共通的風格之一。
✅ 可讀性好
使用 _
能一眼表達「我知道這個值存在,但此處不打算使用」,讓其他閱讀程式的人更快理解邏輯,也避免誤解為「作者忘了寫」或「命名錯誤」。
這對團隊合作尤為重要。
✅ 保持簽名一致
保留所有參數結構(即使不使用)能避免函式簽名對位錯誤,未來若有新需求,也能直接替換 _
為具體變數名,可擴充性高。
尤其在 callback 或 API handler 中更是實用。
✅ 與工具鏈整合佳
ESLint、TypeScript 等靜態分析工具能透過設定辨識以 _
命名的參數是「刻意不使用」,從而避免報錯或顯示不必要的警告。
例如透過 ESLint 的 argsIgnorePattern
就能忽略所有 _
開頭的未使用變數。這樣能讓程式碼更乾淨、更可維護。
學會如何適當使用 _
來忽略參數,不僅可以讓你的程式碼更簡潔,也能提升團隊溝通效率與工具整合性。
不過,最重要的是記得這只是開發者間的語意慣例,請根據具體情境合理使用、避免濫用,這樣才能發揮它的最大效益。