模板字面量

js/template_literals2026-10-29 11:03:47

模板字面量 是用反引号(`)分隔的字面量,允许多行字符串、带嵌入表达式的字符串插值和一种叫带标签的模板的特殊结构。

模板字面量有时被非正式地叫作 模板字符串,因为它们最常被用作字符串插值(通过替换占位符来创建字符串)。然而,带标签的模板字面量可能不会产生字符串——它可以与自定义标签函数一起使用,来对模板字面量的不同部分执行任何操作。

模板字面量用反引号(`)括起来,而不是双引号(")或单引号(')。 除了普通字符串外,模板字面量还可以包含占位符——一种由美元符号和大括号分隔的嵌入式表达式:${expression}。字符串和占位符被传递给一个函数(要么是默认函数,要么是自定义函数)。默认函数(当未提供自定义函数时)只执行字符串插值来替换占位符,然后将这些部分拼接到一个字符串中。

语法

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tagFunction`string text ${expression} string text`
  • string text:将成为模板字面量的一部分的字符串文本。几乎允许所有字符,包括换行符和其他空白字符。但是,除非使用了标签函数,否则无效的转义序列将导致语法错误。

  • expression:要插入当前位置的表达式,其值被转换为字符串或传递给 tagFunction。

  • tagFunction:如果指定,将使用模板字符串数组和替换表达式调用它,返回值将成为模板字面量的值。见带标签的模板。

转义

若要转义模板字面量中的反引号(`),需在反引号之前加一个反斜杠(\)。

`\`` === "`"; // true

美元符号 $ 也可以被转义,来阻止插值。

`\${1}` === "${1}"; // true

模板插值

有了模板字面量,就可以通过使用占位符 ${expression} 嵌入待替换的表达式,从而避免使用加法运算符 + 连接它们,并提高代码的可读性:

const a = 5;
const b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

注意,这两种语法有一点小区别:模板字面量直接将其表达式强制转换为字符串,而加法则会先强制转换为原语类型。

带标签的模板

带标签的模板是模板字面量的一种更高级的形式,它允许你使用函数解析模板字面量。

使用自定义标签

若要提供自定义函数,需在模板字面量之前加上函数名(结果被称为带标签的模板)。此时,模板字面量被传递给你的标签函数,然后就可以在那里对模板文本的不同部分执行任何操作。

例如,使用带有标签 myTag 的模版:

const output = myTag`That ${person} is a ${age}.`;

定义标签函数

标签函数的第一个参数包含一个字符串数组,其余的参数与表达式相关。你可以用标签函数对这些参数执行任何操作,并返回被操作过的字符串。用作标签的函数名没有限制。

标签函数甚至不需要返回字符串!

下面是标签函数的实例:

function myTag(strings, personExp, ageExp) {
  const str0 = strings[0]; // "That "
  const str1 = strings[1]; // " is a "
  const str2 = strings[2]; // "."

  const ageStr = ageExp > 99 ? "centenarian" : "youngster";

  // 我们甚至可以返回使用模板字面量构建的字符串
  return `${str0}${personExp}${str1}${ageStr}${str2}`;
}

运行结果如下:

const person = "Mike";
const age = 28;

const output = myTag`That ${person} is a ${age}.`;

console.log(output);
// That Mike is a youngster.

使用表达式作为标签

标签不必是普通的标识符,你可以使用任何优先级大于 16 的表达式,包括属性访问、函数调用、new 表达式,甚至其他带标签的模板字面量。

console.log`Hello`; // [ 'Hello' ]
console.log.bind(1, 2)`Hello`; // 2 [ 'Hello' ]
new Function("console.log(arguments)")`Hello`; // [Arguments] { '0': [ 'Hello' ] }

function recursive(strings, ...values) {
  console.log(strings, values);
  return recursive;
}
recursive`Hello``World`;
// [ 'Hello' ] []
// [ 'World' ] []

如果用作标签的表达式不是函数,会报错:

console.log(`Hello``World`); // TypeError: "Hello" is not a function

参考

模板字面量
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Template_literals

本页目录