在 JavaScript 中,我們經常需要檢查一個字串是否包含某個特定的字元或子字串。本文比較三種常用方法:indexOf()、includes() 和 filter(),涵蓋語法、可讀性、相容性與效能差異。
1. indexOf() 方法
indexOf() 是最古老且支援度最廣的方法之一。
語法
1 | string.indexOf(searchValue[, fromIndex]) |
用法
1 | const str = "Hello, World!"; |
優點
- 相容性好,支援舊版瀏覽器
- 可以指定開始搜尋的位置
缺點
- 返回值不是布林型,需要與 -1 比較
- 程式碼可讀性較差
2. includes() 方法
includes() 是 ES6 引入的方法,專門用於檢查字串是否包含特定子字串。
語法
1 | string.includes(searchString[, position]) |
用法
1 | const str = "Hello, World!"; |
優點
- 直接返回布林值,更直觀
- 程式碼更簡潔,可讀性強
- 可以指定開始搜尋的位置
缺點
- 不支援正規表達式
- 在舊版瀏覽器中可能需要 polyfill
3. filter() 方法
filter() 是陣列方法,可以搭配 Array.from() 將字串拆成字元陣列後進行篩選。不過要注意:這種寫法只適合單一字元比對,無法用來搜尋多字元子字串(例如 'World' 或 'lo')。若要搜尋子字串,仍須搭配 includes() 或 indexOf()。
語法
1 | // 注意:此語法只能逐字元比對,不能搜尋多字元子字串 |
用法
1 | const str = "Hello, World!"; |
優點
- 靈活性高,可以對字元套用複雜的條件篩選
- 可以同時篩選多種字元(搭配陣列或
||條件)
缺點
- 只能比對單一字元,無法直接搜尋多字元子字串
- 語法較為複雜
- 效能較差,特別是對於長字串;若只需判斷是否存在,應改用
Array.from(str).some(c => c === searchChar),短路後即停、效能遠勝filter
效能比較
為了比較這三種方法的效能,可以進行一個簡單的基準測試:
1 | const str = "Hello, World!".repeat(1000000); // 建立一個長字串 |
在單機測試中得到以下數字(僅供方向參考,實際數值因 JS 引擎版本、硬體與測試環境差異顯著):
- indexOf: 約 5ms
- includes: 約 7ms
- filter: 約 15000ms
兩者 2ms 的差距落在量測雜訊範圍,不代表 indexOf 系統性優於 includes;filter 慢上千倍這個方向是可重現的結論。
結論
- 效能:
indexOf()與includes()在現代 JavaScript 引擎(V8、SpiderMonkey)上效能幾乎相同,差距落在量測雜訊範圍內,不構成選用依據。filter慢上千倍的差距在任何字串長度下都會出現,選用時必須考慮。 - 可讀性:
includes()最清晰直觀。 - 靈活性:
filter()可套用複雜條件,但若只需判斷存在與否,some()是更正確的替代(短路停止,不掃完整個陣列)。
選用建議
- 一般字元或子字串搜尋,用
includes()。 - 需相容舊版瀏覽器,或需要取得字元的位置索引,用
indexOf()。 - 需複雜條件篩選且可接受只比對單一字元,優先考慮
some();只有需要收集所有符合字元時才用filter()。 - ES6 起也有
startsWith()和endsWith()可直接判斷前後綴,不必用indexOf配合位置 0 來繞。
參考資源
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 kyosora 筆記!
評論





