模板字面量是JavaScript中唯一原生支持多行字符串、表达式插值和标签函数的字符串语法,须用反引号包裹,${...}内表达式强制转字符串,null/undefined变为字面量,换行缩进需手动处理,String.raw可禁用转义序列。

模板字面量(template literal)不是“更高级的字符串拼接”,而是 JavaScript 中唯一能原生支持多行字符串、表达式插值和标签函数的字符串语法。用错地方或忽略细节,很容易掉进静默失败或安全漏洞的坑里。
怎么写一个基础模板字面量
必须用反引号 ` 包裹,不能用单引号或双引号。里面用 ${...} 插入任意表达式,包括变量、函数调用、甚至三元运算符。
`Hello ${name}, you have ${count || 0} new message${count === 1 ? '' : 's'}.`
注意:${...} 里的内容会强制转为字符串(调用 .toString()),但 null 和 undefined 会变成字面量字符串 "null" 或 "undefined",不是空字符串。
- 别用
'Hello ${name}'—— 单引号下${name}就是纯文本 -
${}内部不能有未声明变量,否则运行时报ReferenceError - 如果只是想输出字面量
${foo},得写成$\{foo\}(用反斜杠转义)
换行和缩进怎么处理才不混乱
模板字面量天然支持换行,但缩进空格也会原样输出,容易让 HTML 或 JSON 输出带多余空白。
立即学习“Java免费学习笔记(深入)”;
``Hello ${name}
上面这段生成的 HTML 中, 1、对ASP内核代码进行DLL封装,从而大大提高了用户的访问速度和安全性;2、采用后台生成HTML网页的格式,使程序访问速度得到进一步的提升;3、用户可发展下级会员并在下级购买商品时获得差额利润;4、全新模板选择功能;5、后台增加磁盘绑定功能;6、后台增加库存查询功能;7、后台增加财务统计功能;8、后台面值类型批量设定;9、后台财务曲线报表显示;10、完善订单功能;11、对所有传输的字符串进行安全 前有两个空格,
前也有两个空格。解决方法:
- 用
.trim()去首尾空白:htmlString.trim() - 用
.replace(/\s+/g, ' ')合并内部多余空白(慎用,会吃掉 pre 标签需要的空格) - 更稳妥的是把换行符和缩进逻辑写进模板里:
``Hello ${name}
为什么 String.raw 有时比普通模板字面量更安全
普通模板字面量会解析转义序列,比如 \n 变成换行符、\t 变成制表符。如果你在正则、文件路径或 SQL 片段里拼接字符串,这种自动解析可能破坏原始意图。
const path = `C:\temp\file.txt`; // 实际得到 "C:" + 换行 + "emp" + 制表符 + "ile.txt" const rawPath = String.raw`C:\temp\file.txt`; // 正确得到字面量 "C:\\temp\\file.txt"
String.raw 是一个标签函数,它让模板字面量跳过所有反斜杠转义处理。注意:它不阻止 ${...} 插值,只禁用转义序列解析。
- 正则字面量中写
/\d+\.\d+/没问题,但拼接时用new RegExp(`${prefix}\\d+\\.\\d+`)容易漏掉双反斜杠 - 用
String.raw`...${prefix}...`能避免手动加四层反斜杠 -
String.raw不是模板字面量的“升级版”,而是不同用途的工具:一个用于人读友好的结构化字符串,一个用于机器精确的原始字节流
标签函数里 strings 和 values 到底是什么
自定义标签函数接收两个关键参数:strings(静态片段数组)和 values(插值表达式结果数组)。它们长度关系永远是 strings.length === values.length + 1。
function highlight(strings, ...values) {
let result = '';
for (let i = 0; i < strings.length; i++) {
result += strings[i];
if (i < values.length) {
result += `${values[i]}`;
}
}
return result;
}
const name = 'Alice';
highlight`Hello ${name}! You're logged in.`;
// → ["Hello ", "! You're logged in."] 和 ["Alice"]
这个机制常被用于 CSS-in-JS 库(如 styled-components)、SQL 参数化(防止注入)、国际化(提取待翻译文本)等场景。但要注意:
-
strings中的每个元素都已去除插值部分,且保留原始换行与空格 -
values是运行时求值结果,不是源码字符串,所以无法做静态分析 - 不要在标签函数里直接拼接用户输入到 HTML,仍需手动转义或使用 DOM API
模板字面量看着简单,但一旦涉及跨环境(Node.js / 浏览器 / Deno)、跨用途(HTML / SQL / CLI 命令)、跨信任边界(用户输入),那些默认行为就不再是“方便”,而是隐患源头。










