为什么在使用模板字符串时可以调用不带括号的函数?

Why can functions be called without parentheses when using template strings?

我有一个简单的日志功能:

function log(str) {
  console.log('logged: ', str);
}

如果我不带括号调用它(目前使用 Chrome 的开发工具)并传入模板字符串,如下所示:

log`foo`

输出为:logged: ["foo", raw: Array[1]]

如果我用括号调用它,

log(`foo`)

输出为:logged: foo

为什么在 Javascript 中使用模板字符串调用没有括号的函数有效?发生了什么导致结果与用括号调用它不同?

第一个示例 (log`foo`) 允许语言规范确定传递给日志函数的值(参见 12.3.7)。第二个示例 (log(`foo`)) 明确传递了一个参数。

模板文字可以包含字符串和表达式。有时您可能希望从字符串部分和表达式部分更好地控制字符串的编译。在这种情况下,您可能正在寻找带标签的模板。

var name = "Jonathan";
var mssg = foo `Hello, ${name}. Nice name, ${name}.`;

function foo ( strings, ...values ) {
    console.log( strings ); //["Hello, ", ". Nice name, ", ".", raw: Array[3]]
    console.log( values  ); //["Jonathan", "Jonathan"]
}

注意这里所有的字符串是如何通过第一个参数传入的。同样,所有的内插值表达式都通过其余参数传入(在这里被拉到一个数组中)。

有了这个添加的控件,我们可以做各种各样的事情,比如本地化。在此示例中,语言规范确定要传递给函数的适当值 — 开发人员未确定这一点。

相比之下,当您调用 log(<code>foo) 时,您最终会得到 结果字符串。没有对象,没有零件,没有原始值。