本文 AI 產出,尚未審核

JavaScript ES6+ 新特性:模板字串(Template Literals)

簡介

在傳統的 JavaScript 中,字串只能使用單引號 (') 或雙引號 ("),若要在字串內插入變數或運算結果,往往需要透過繁瑣的串接 (+) 操作。
ES6(ECMAScript 2015)引入的 模板字串(Template Literals)則以反引號 (`) 包裹,支援 字串插值多行文字,以及 標籤模板(Tagged Templates)等強大功能,讓程式碼更簡潔、可讀性更高。

對於 初學者,模板字串是學習現代 JavaScript 必備的基礎;對 中級開發者,則是撰寫動態 UI、產生 SQL/HTML 片段、或實作國際化(i18n)時不可或缺的工具。本文將從概念說明、實作範例、常見陷阱到最佳實踐,完整介紹模板字串的使用方式。


核心概念

1. 基本語法:使用反引號與 ${} 插值

const name = 'Alice';
const age = 28;

// 以前的寫法
const messageOld = 'Hello, ' + name + '! You are ' + age + ' years old.';
// 使用模板字串
const messageNew = `Hello, ${name}! You are ${age} years old.`;

console.log(messageOld); // Hello, Alice! You are 28 years old.
console.log(messageNew); // Hello, Alice! You are 28 years old.
  • 反引號 (`) 包住整段字串。
  • ${expression} 內可以放 任意 JavaScript 表達式,會在執行時自動轉為字串。

2. 多行字串(Multi-line Strings)

傳統字串若要跨行,需要使用 \n 或字串連接。模板字串直接保留換行符號,讓原始排版即為最終結果。

const poem = `靜夜思
床前明月光,
疑是地上霜。
舉頭望明月,
低頭思故鄉。`;

console.log(poem);

提示:字串內的縮排會被保留,若不想保留前導空白,可在模板前後使用 .trim()

3. 表達式與函式呼叫

${} 不只能放變數,還能直接寫運算或呼叫函式,讓字串產生更具彈性。

function formatCurrency(num) {
  return `$${num.toFixed(2)}`;
}

const price = 1234.5;
const receipt = `Total: ${formatCurrency(price)} (含稅)`;

console.log(receipt); // Total: $1234.50 (含稅)

4. 標籤模板(Tagged Templates)

標籤模板允許在字串被解析前先「攔截」字串與插值,常用於 自訂語言安全過濾、或 國際化

// 標籤函式:簡易的 HTML 轉義
function escapeHTML(strings, ...values) {
  const escape = (str) =>
    str.replace(/[&<>"']/g, (c) =>
      ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;'
      }[c])
    );

  return strings.reduce((result, str, i) => {
    const val = values[i] !== undefined ? escape(String(values[i])) : '';
    return result + str + val;
  }, '');
}

const userInput = '<script>alert("XSS")</script>';
const safeHTML = escapeHTML`<p>使用者說:${userInput}</p>`;

console.log(safeHTML);
// <p>使用者說:&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;</p>

關鍵:標籤函式的第一個參數是 字串陣列(已分割的文字),之後的參數則是對應的插值值。

5. 逃脫反引號與 ${}

若字串本身需要包含反引號或 ${},必須使用 反斜線\)逃脫。

const raw = `這是一個反引號:\`,以及插值符號 \${notAVariable}`;
console.log(raw);
// 這是一個反引號:`,以及插值符號 ${notAVariable}

常見陷阱與最佳實踐

陷阱 說明 建議的做法
忘記使用反引號 用單/雙引號寫 ${} 會被當成普通字串,插值不會被解析。 務必使用 ` 包住整段字串
不必要的空白與縮排 模板字串保留所有換行與空格,會導致輸出多餘的空白。 使用 .trim().replace(/\s+/g, ' ') 或將縮排寫在行首。
在插值中執行副作用 ${func()} 會在字串組合時立即執行,若 func 有副作用會影響程式行為。 避免在插值中呼叫會改變狀態的函式,僅使用純函式或預先計算結果。
大量模板字串的效能 產生極大量的模板字串(例如在迴圈內)會產生許多臨時字串物件。 若效能成問題,可改用 Array.join模板函式 緩存結果。
安全性:XSS 攻擊 直接把使用者輸入插入 HTML 會產生 XSS 風險。 使用 標籤模板 進行 HTML 轉義,或使用前端框架的自動編碼機制。

最佳實踐

  1. 保持插值純粹:將計算或資料取得的工作放在模板外,插值只負責顯示。
  2. 使用標籤模板做安全過濾:如上例的 escapeHTML,或利用第三方庫(如 lodash.escape)。
  3. 適度使用 .trim():避免因排版而產生不必要的前後空白。
  4. 統一風格:在團隊中約定「模板字串皆使用反引號,且每行縮排以 2 空格為基準」。
  5. 避免過度嵌套:過長的模板字串可拆成小片段,使用函式組合,提高可讀性。

實際應用場景

1. 動態 URL 組合

function buildApiUrl(endpoint, params) {
  const query = new URLSearchParams(params).toString();
  return `https://api.example.com/${endpoint}?${query}`;
}

const url = buildApiUrl('search', { q: '模板字串', page: 2 });
console.log(url);
// https://api.example.com/search?q=%E6%A8%A1%E6%9D%BF%E5%AD%97%E4%B8%B2&page=2

2. 產生 HTML 片段(搭配安全過濾)

function renderUserCard(user) {
  return escapeHTML`
    <div class="card">
      <h2>${user.name}</h2>
      <p>年齡:${user.age}</p>
      <p>簡介:${user.bio}</p>
    </div>
  `;
}

3. 多語系訊息(i18n)

const messages = {
  en: (name) => `Welcome, ${name}!`,
  zh: (name) => `歡迎,${name}!`,
};

function greet(lang, name) {
  return messages[lang]?.(name) ?? messages.en(name);
}

console.log(greet('zh', '小明')); // 歡迎,小明!

4. 日誌與除錯

function logError(err, context) {
  console.error(`❌ 錯誤於 ${context.module}
訊息: ${err.message}
堆疊: ${err.stack}`);
}

5. 生成 SQL 查詢(注意避免 SQL 注入)

重要提醒:永遠使用參數化查詢(prepared statements)避免注入,此處僅示範模板字串的排版便利性。

function buildSelect(table, columns, where) {
  const cols = columns.join(', ');
  const conditions = Object.entries(where)
    .map(([k, v]) => `${k} = '${v.replace(/'/g, "''")}'`) // 簡易轉義
    .join(' AND ');
  return `SELECT ${cols}
FROM ${table}
WHERE ${conditions};`;
}

const sql = buildSelect('users', ['id', 'name'], { status: 'active', role: 'admin' });
console.log(sql);

總結

模板字串是 ES6+ 中最直觀、最具表現力的字串處理工具。透過反引號、${} 插值與標籤模板,我們可以:

  • 簡化字串拼接,提升程式可讀性。
  • 直接書寫多行文字,免除繁瑣的換行符號。
  • 在字串生成前進行安全過濾,降低 XSS、SQL 注入等風險。
  • 在實務開發(API URL、HTML 產生、國際化、日誌)中提供一致且易維護的寫法。

掌握模板字串的正確使用與常見陷阱,能讓你在 前端Node.js全端 專案中寫出更乾淨、更安全的程式碼。未來隨著 Tagged Templates 的生態(例如 styled-componentsgraphql-tag)持續擴展,模板字串將成為 JavaScript 開發者不可或缺的基礎能力。祝你在 Modern JS 的旅程中,玩得開心、寫得順手!