用反引号的模板字符串替代+拼接是最直接方案,支持变量插值、多行和表达式嵌入,但须防XSS、注意性能及兼容性问题。

用 template literals 替代 + 拼接是最直接的方案
ES6 引入的模板字符串(template literals)用反引号 ` 包裹,支持嵌入表达式 ${...},天然解决多行、变量插值、转义混乱等问题。相比 + 连接或 String.concat(),它更易读、更少出错。
常见错误是误用单引号或双引号包裹模板,导致 ${...} 不被解析——必须用反引号。
- 变量插值写法:
`Hello ${name}, you have ${count} messages` - 支持多行:
`Line 1 Line 2 Value: ${x}` - 可嵌套表达式:
`Total: ${items.reduce((a, b) => a + b.price, 0).toFixed(2)}` - 注意:空模板
``是合法字符串,但${undefined}会变成字符串"undefined",需自行判空
需要动态拼接大量字符串时,避免重复创建中间字符串
JavaScript 字符串不可变,每次 + 或模板拼接都会生成新字符串。在循环中高频拼接(如生成 HTML 列表)可能触发内存抖动。
此时应改用数组累积再 .join(''),尤其适用于已知分隔符的场景:
立即学习“Java免费学习笔记(深入)”;
- 错误示范(性能差):
let html = ''; for (const item of list) { html += `${item.name}`; } - 推荐写法(高效):
const parts = []; for (const item of list) { parts.push(`${item.name}`); } const html = parts.join(''); - 若用
map+join更简洁:list.map(item => `${item.name}`).join('')
处理用户输入或外部数据时,模板拼接必须防 XSS
直接把未过滤的变量插入模板字符串(尤其是 HTML 场景)等于主动引入 XSS 风险。模板字符串本身不提供转义能力,这点常被忽略。
- 危险示例:
`—— 若${userInput}`userInput是,就执行了脚本 - 服务端渲染需用专用转义函数,如 Node.js 的
he.escape();浏览器端可用DOMPurify.sanitize()或手动替换:function escapeHtml(str) { return str .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } `${escapeHtml(userInput)}` - 框架(React/Vue)自带转义机制,但使用
dangerouslySetInnerHTML或v-html时仍需手动处理
旧环境兼容性不足时,用 String.prototype.replace 模拟简单模板
若目标环境不支持 ES6(如 IE),又不想引入完整模板引擎,可用 replace 实现键值替换。但仅适合静态键名、无逻辑表达式的场景。
- 基础实现:
function simpleTemplate(str, data) { return str.replace(/\$\{(\w+)\}/g, (match, key) => data[key] ?? ''); } simpleTemplate('Hello ${name}!', { name: 'Alice' }); // "Hello Alice!" - 注意正则中的
\$\{(\w+)\}必须双反斜杠转义,否则$和{会被正则解释为特殊字符 - 不支持嵌套表达式、函数调用、条件判断,复杂需求请上
lodash.template或mustache
${}、拼大量内容时不意识性能、往 HTML 里塞变量却忘了转义。这三处比语法本身更值得反复检查。











