本文 AI 產出,尚未審核

JavaScript 字串操作:includesstartsWithendsWith

簡介

在前端開發或 Node.js 後端程式中,字串是最常見的資料型別之一。無論是驗證使用者輸入、解析 API 回傳的文字,或是動態產生 UI,常都需要判斷字串是否包含特定子字串,或是以什麼字元開頭/結尾。
ECMAScript 6 為 String 物件新增了三個直觀且效能良好的方法:includes()startsWith()endsWith()。相較於舊式的 indexOf()、正規表達式等寫法,這三個方法語意更清楚、使用更安全,也更符合「可讀性」的程式設計原則。

本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,帶你全面掌握這三個字串方法,並提供實務上常見的應用情境,協助你在日常開發中寫出更簡潔、易維護的程式碼。

核心概念

1. String.prototype.includes(searchString, position?)

includes() 用來判斷 字串中是否出現 指定的子字串,回傳布林值 truefalse。第二個參數 position(可選)表示搜尋的起始索引,預設為 0

const text = "JavaScript 是最受歡迎的前端語言。";

// 基本用法
console.log(text.includes("受歡迎")); // true

// 指定起始位置
console.log(text.includes("前端", 20)); // false,因為從 index 20 開始找不到「前端」
// 若不提供 position,會從頭開始搜尋

小技巧includes() 對空字串 "" 永遠回傳 true,因為任何字串都「包含」空字串。


2. String.prototype.startsWith(searchString, position?)

startsWith() 檢查 字串是否以 指定子字串開頭,同樣回傳布林值。position 參數允許你指定「從哪個位置開始當作字串的起點」進行檢查。

const url = "https://developer.mozilla.org/zh-TW/docs/Web/JavaScript";

// 判斷是否為安全的 https 網址
if (url.startsWith("https://")) {
  console.log("安全連線");
}

// 從第 8 個字元開始檢查(跳過 "https://")
console.log(url.startsWith("developer", 8)); // true

注意startsWith() 只會檢查 單一位置,不會搜尋整個字串。


3. String.prototype.endsWith(searchString, length?)

endsWith() 用於判斷 字串是否以 指定子字串結尾。第二個參數 length(可選)表示「視為字串的長度」,可用來在不改變原字串的情況下,只檢查子字串的前半部分。

const fileName = "report_2024.pdf";

// 檢查副檔名是否為 .pdf
console.log(fileName.endsWith(".pdf")); // true

// 只檢查前 12 個字元是否以 "_2024" 結尾
console.log(fileName.endsWith("_2024", 12)); // true

4. 為什麼要使用這三個方法?

方法 主要用途 相較於舊寫法的優勢
includes 判斷是否包含子字串 語意清晰、避免 -1 判斷
startsWith 判斷開頭 不必手動切片或使用正規表達式
endsWith 判斷結尾 同上,且支援 length 參數

程式碼範例

以下提供 5 個實用範例,示範在不同情境下如何結合 includesstartsWithendsWith

範例 1:表單驗證 – 電子郵件格式檢查

function isValidEmail(email) {
  // 必須同時包含 "@" 且以 ".com"、".org"、".net" 結尾
  return email.includes("@") && 
         (email.endsWith(".com") || email.endsWith(".org") || email.endsWith(".net"));
}

console.log(isValidEmail("test@example.com")); // true
console.log(isValidEmail("invalid-email"));    // false

範例 2:路由權限判斷

function hasAccess(route) {
  // 只允許以 "/admin" 開頭且不以 "/public" 結尾的路徑
  return route.startsWith("/admin") && !route.endsWith("/public");
}

console.log(hasAccess("/admin/dashboard"));   // true
console.log(hasAccess("/admin/public"));      // false

範例 3:檔案類型過濾(多副檔名)

const allowedExt = [".png", ".jpg", ".jpeg", ".gif"];

function isImage(fileName) {
  return allowedExt.some(ext => fileName.toLowerCase().endsWith(ext));
}

console.log(isImage("avatar.PNG")); // true
console.log(isImage("document.pdf")); // false

範例 4:搜尋功能 – 只在文字開頭顯示結果

const products = ["Apple iPhone", "Samsung Galaxy", "Google Pixel", "Apple Watch"];

function filterByPrefix(keyword) {
  return products.filter(p => p.toLowerCase().startsWith(keyword.toLowerCase()));
}

console.log(filterByPrefix("apple")); // ["Apple iPhone", "Apple Watch"]

範例 5:多語系支援 – 判斷語系代碼是否在支援清單內

const supportedLang = ["en-US", "zh-TW", "ja-JP", "fr-FR"];

function isSupported(locale) {
  // 檢查完整代碼或僅檢查語言前兩碼(如 "zh")
  return supportedLang.includes(locale) || 
         supportedLang.some(code => code.startsWith(locale.split("-")[0]));
}

console.log(isSupported("zh-TW")); // true
console.log(isSupported("zh"));    // true(因為支援 zh-??)
console.log(isSupported("de"));    // false

常見陷阱與最佳實踐

陷阱 說明 解決方式
大小寫不一致 includesstartsWithendsWith區分大小寫 的比較。 在比較前使用 toLowerCase()toUpperCase() 正規化字串。
傳入非字串 searchString 不是字串,會自動呼叫 ToString,但可能產生意料外結果。 事先確保參數為字串,或使用 String(searchString) 強制轉型。
空字串的行為 ''.includes('')''.startsWith('')''.endsWith('') 都回傳 true 若不想讓空字串通過,額外檢查 searchString.length > 0
position 參數的負值 position 為負值時會被視為 0,可能導致搜尋結果與預期不符。 使用 Math.max(0, position) 保障正確性。
Unicode 正規化 某些 Unicode 字元(如結合音)在不同表示方式下可能不相等。 若需精確比對,先使用 String.prototype.normalize()

最佳實踐

  1. 明確命名:將判斷結果包裝成語意清楚的函式(如 isValidEmail),提升可讀性。
  2. 避免硬編碼:將檔案副檔名、語系代碼等陣列抽離為常數或設定檔,方便維護。
  3. 結合陣列方法:使用 some()every() 搭配字串方法,可寫出更具宣告性的條件式。
  4. 效能考量:若要在大量資料上重複檢查,先把常用的字串轉成小寫或正規化,減少重複運算。

實際應用場景

  1. 前端路由守衛:在單頁應用(SPA)中,使用 startsWith('/admin') 判斷使用者是否正嘗試進入管理區,結合身份驗證機制決定是否導向登入頁。
  2. 檔案上傳驗證:透過 endsWith() 檢查上傳檔案的副檔名,配合 Array.some() 篩選允許的類型,避免不安全檔案被寫入伺服器。
  3. 搜尋自動完成:在搜尋框即時顯示結果時,使用 startsWith() 只列出以關鍵字開頭的項目,提升使用者體驗。
  4. 國際化 (i18n) 文字切換:根據使用者的瀏覽器語系(如 navigator.language),使用 startsWith() 判斷是否支援對應語系,決定載入哪套語系檔案。
  5. 內容過濾:在聊天室或評論系統中,利用 includes() 快速檢測是否含有敏感詞彙,結合正規表達式做更精細的過濾。

總結

includes()startsWith()endsWith()ES6 之後字串處理的核心工具,提供了直觀且效能佳的子字串檢查方式。透過本文的概念說明、實作範例與最佳實踐,你應該已能:

  • 正確判斷字串是否包含、開頭或結尾指定文字。
  • 處理大小寫、空字串與 Unicode 正規化等常見問題。
  • 在表單驗證、路由守衛、檔案過濾、搜尋與國際化等實務情境中靈活運用。

掌握這三個方法後,未來在處理文字相關的需求時,你將能寫出 更簡潔、可讀性更高且更不易出錯 的程式碼。祝你在 JavaScript 的字串世界裡玩得開心,也期待看到你把這些技巧帶入實際專案中!