字符串插值
JavaScript 中使用反引号 ` 包裹的字符串叫模板字符串(template literals)。人们常用它拼接变量和字符串,即所谓的字符串插值(string interpolation)。在使用字符串插值时,使用 ${} 包裹变量或表达式,它是变量的占位符。
多行文本
模板字符串支持多行文本(multi-line strings)。
嵌套模板
它还支持嵌套模板(nesting templates)。即在一个模板字符串的变量内,使用另一个模板字符串。
带标签的模板
它还有另外一个略显高级的用法:带标签的模板(tagged templates),有时也叫标签函数(tag function),指的都是一回事。
在带标签的模板中,标签其实是一个函数,它可以处理模板字符串的内容。该函数的第一个参数是字符串数组,包括模板字符串的所有静态字符字面量,后面的不定参数,按照先后顺序分别对应 ${} 对应的变量。
函数返回值会当作模板字符串变量的最终值。只要你想,返回值可以和入参完全无关。
标签函数属于可变参数函数(variadic functions),在 JavaScript 中可以使用三个点 ... 剩余参数(rest parameters)语法,将所有的变量收集到一个数组。
标签函数的返回值可以是任意类型,不一定是字符串。
除了普通变量,带标签模板的“标签”还可以是表达式,只要它的操作符优先级大于 16 即可。满足条件的表达式有属性访问 x.y、函数调用 x(y)、创建对象 new x(y),甚至另一个标签模板字面量。
带标签模板的实际应用有哪些?如果你接触过谷歌的 zx 命令行工具,或者谷歌的 Lit 框架(谷歌真喜欢用它),就会见到它的实际用法。下图中的 $ 和 html 就是标签函数。
参考资料
Tagged templates
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
google/zx
https://github.com/google/zx
Lit
https://lit.dev/
Rest parameters
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
Operator precedence
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table