模板文字和无括号函数调用

问题描述

我最近了解到,当使用模板字面量作为参数时,ES6 允许进行不带括号的函数调用。例如

showstring`Hello World`;

然而,在阅读了一些关于此功能文章后,我对 JS 如何处理这些调用背后的逻辑知之甚少。

在对我的代码进行了一些排列之后,我仍然在努力拼凑模板文字函数内部如何在人们以这种方式调用时分解的模式。

const showstring = (str) => {
  console.log(str);
}
showstring`Hello World`;

上面代码中发生的事情很简单,字符串文字作为数组接收,其中第一个也是唯一的元素是字符串。

一旦我开始在模板中使用表达式,就会让人有点困惑。例如

const showstring = (str,...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring`Hello World ${name} ${name} ${1 + 2} and more`;

所以看起来 ...values 部分解构了所有的表达式。但是,为什么 str 数组在这些位置有空字符串?

我只是没有完全理解它在这里遵循的模式。有人可以解释一下这个功能吗?或者给我推荐一篇好文章

解决方法

在第二个代码片段中,记录了这些:

// str
[
  "Hello World "," "," and more"
]

// values
[
  "John","John",3
]

如果这些“空字符串”是指 str 数组的第 2 项和第 3 项,则它们不是空字符串;它们是带有单个空格的字符串。它们来自模板文字中表达式之间的空格:

showstring`Hello World ${name} ${name} ${1 + 2} and more`;
//                            ^       ^

当模板文字前面有表达式时——在本例中为 showstring——它被称为 tagged template

在您的 showstring 函数中,str 总是比 values 数组多包含一项。例如。看看这些日志是什么:

const showstring = (str,...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring``;
showstring`${name}`;
showstring`Hello ${name}!`;

这不是特定于您的功能;这就是标记模板的工作方式。来自Tagged templates section in the book JavaScript for impatient programmers (ES2020 edition)

第一个反引号之前的函数称为标签函数。 它的参数是:

  • 模板字符串(第一个参数):包含围绕插值 ${} 的文本片段的数组。
  • 替换(剩余参数):插值。

关于您的评论:

有趣的是, 那个单一的空间将永远是一个单一的空间 无论您在表达式之间放置多少空格 调用函数时。 知道为什么它只修剪一个空格吗?

这似乎并非如此。这会记录一个包含三个空格的字符串:

const showstring = (str,...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring`Hello ${name}   ${name}!`;

您是否可能将结果打印到 DOM?除非您使用 <pre>white-space: pre; 或类似的东西,否则多个空格仅显示为一个,因此结果似乎被修剪为一个空格。