模板字符串用反引号包裹,支持变量插值、换行和多行拼接,非语法糖而是语言必要补充;可触发标签函数实现转义、国际化等高级功能,且空白符原样保留。
模板字符串不是“更强”,而是解决了一类普通字符串根本做不到的事——比如嵌入变量、换行、多行文本拼接。它用 `(反引号)包裹,不是语法糖,是语言层面的必要补充。
普通字符串用单引号或双引号,不能直接换行,也不能写 ${variable};模板字符串必须用反引号 `,里面可以自由换行,还能用 ${...} 插入任意表达式。
常见错误:把反引号写成单引号,或者在模板里漏掉 $ 直接写 {name}——这不会报错,但也不会替换,原样输出。
${a + b}、${items.length > 0 ? 'yes' : 'no'}
${getName()},只要返回值能转成字符串`` 是合法的,值为 "";但 ` `(含空格)就是带空格的字符串`Hello ${name}
You have ${count} new message${count === 1 ? '' : 's'}.`
+ 拼接替代模板字符串纯拼接在简单场景下可行,但一涉及换行、缩进、条件逻辑或嵌套对象,可读性断崖下跌,且容易出错。
典型问题:
\n 和引号嵌套混乱,比如 "line1\nline2" vs `line1\nline2`
'' 容易漏引号或被 XSS 利用;而 `` 结构清晰、天然隔离
- 性能上无本质差异,V8 等引擎对模板字符串做了优化,但关键不在快慢,而在可维护性
标签函数:模板字符串的隐藏能力
模板字符串本身不执行任何逻辑,但它可以作为参数传给函数,触发“标签函数”机制——这才是它真正区别于普通字符串的核心能力。
比如 html`${name}` 中的 html 就是自定义标签函数,接收字符串数组和插值结果作为参数,可用于自动转义、国际化、SQL 参数化等。
- 标签函数第一个参数是字符串字面量数组(如
["", ""])
- 后续参数是每个
${...} 的计算结果(如 name 的值)
- 常见库如
styled-components、graphql 都依赖此机制
- 注意:没有标签的模板字符串(如
`abc`)不会触发该行为
function upper(str
ings, ...values) {
return strings.reduce((acc, str, i) => {
const val = values[i] ? values[i].toUpperCase() : '';
return acc + str + val;
}, '');
}
upper`hello ${'world'} and ${'you'}`; // → "hello WORLD and YOU"
真正容易被忽略的是:模板字符串的换行和空格会原样保留,包括缩进。如果写在缩进很深的代码块里,生成的字符串开头就会有一堆空格——这不是 bug,是设计如此,需要手动 trim 或用工具处理。