标记的模板文字如何在 JavaScript 中工作?

How do tagged template literals work in JavaScript?

考虑以下片段:

let a = (x) => console.log(x);
a`1234`; // prints "Array [ "1234" ]"

为什么在保存匿名函数的变量后面的字符串使函数 运行 将自身作为参数传递到数组中?是否有此行为的任何文档参考?

此外,为什么在使用引号或双引号声明字符串文字时不起作用?

Tagged template literals 采用 (strings: string[], ...values: any[]): any.

的形式

在你的例子中,

let a = (x) => console.log(x);
a`1234`; // prints "Array [ "1234" ]"

x 的类型为 string[],它是所有非内插字符串的数组(基本上任何不在 ${} 内的字符串)。因为没有插值,数组包含一个元素(字符串“1234”)。这是作为第一个参数传递给函数 a.

的内容

只有 template literals 可以 "tagged" 带有函数标识符,这就是为什么您注意到它不适用于单引号或双引号字符串,只能用于反引号。我认为如果您尝试使用常规字符串执行此操作会引发语法错误,但我尚未对此进行测试。

如果您想插入一个值,您可以通过添加附加参数在函数(用作标记)中接收值来实现。请注意,不是单个参数是数组,而是单独的参数。当然,您可以使用扩展运算符 (...) 从它们创建一个数组,如上面的函数签名所示。如 MDN 提供的(修改后的)示例,

const person = 'Mike';
const age = 28;

function tag(strings, person, age) {
  const str0 = strings[0]; // "That "
  const str1 = strings[1]; // " is a "

  // There is technically a string after
  // the final expression (in our example),
  // but it is empty (""), so disregard.
  // const str2 = strings[2];

  const age_description = age > 99 ? 'centenarian' : 'youngster';
  return [str0, name, str1, ageDescription].join('');
}

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

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

请注意,如评论中所示,总是 前导和尾随字符串,即使它恰好为空。因此,如果您以插值开始模板文字,strings[0] 将是一个空字符串。以同样的方式,以插值结尾会留下一个尾随的空字符串,尽管这不是很明显(前导插值将所有索引移动一个,尾随不会影响它们)。