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

时间:2019-02-18 20:45:16

标签: javascript template-literals

请考虑以下代码段:

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

为什么在包含匿名函数的变量之后的字符串使函数运行以本身作为参数传递给Array?是否有任何有关此行为的文档参考?

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

1 个答案:

答案 0 :(得分:3)

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可以用函数标识符“标记”,这就是为什么您注意到它不适用于单引号或双引号的字符串,而仅适用于反引号。我认为,如果您尝试使用常规字符串进行操作,尽管我尚未对其进行测试,但是它将引发语法错误。

如果要插值,可以通过添加其他参数在函数(用作标记)中接收值来实现。注意,不是单个参数是数组,而是单独的参数。当然,您可以使用扩展运算符(...)从它们创建一个数组,如上面的函数签名所示。如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]将是一个空字符串。以相同的方式,以插值结尾会留下一个尾随的空字符串,尽管这种情况并不明显(前导插值会将所有索引都移动一个,尾随不会影响它们)。