ES6使用模板字面量调用函数但没有使用括号

7

根据MDN,标记模板字面量可按如下方式使用:

var a = 5;
var b = 10;
function tag(strings, ...values) {
  alert(strings[0]); // "Hello "
  alert(strings[1]); // " world "
  alert(values[0]); // 15
  alert(values[1]); // 50
  return "Bazinga!";
}
tag `Hello ${ a + b } world ${ a * b }`; // "Bazinga!"

在上面的例子中,函数tag被调用时没有使用括号。
我原本以为应该像tag(`Hello`)这样调用,但那会将模板字面量生成的字符串作为参数传递给函数的strings参数。
不使用括号但带参数调用函数的特殊功能是什么?

你能否在那个示例源代码中添加一个链接? - JSelser
4
标签模板:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals 。这就是它的语法。它本身就很特别。 - Felix Kling
这是我第一次看到一个函数被调用时没有加上 ()。起初以为它是一种简写符号,但很快检查发现不是这样。 - aWebDeveloper
有人可以解释一下为什么会有负面评价吗? - aWebDeveloper
1
例如,new 运算符:new Foo。当然还有 callapply(它们也是函数,但你不需要使用括号来调用函数本身)。 - Felix Kling
显示剩余5条评论
1个回答

6

函数不带括号的特殊调用方式是什么?

标记模板语法简单地允许语法

MemberExpression : MemberExpression TemplateLiteral
CallExpression : CallExpression TemplateLiteral

这些规则意味着,MemberExpressionCallExpression后跟一个TemplateLiteral被视为函数调用。 规范的附加说明如下:

标记模板是一个函数调用,其中调用的参数来自TemplateLiteral(12.2.9)。 实际参数包括模板对象(12.2.9.3)和评估TemplateLiteral中嵌入的表达式产生的值。

如果您想知道为什么要这样做,我无法回答。
然而,如果你仔细考虑一下,就会发现不能只使用“普通”的函数调用语法。tag(`...`)表示将模板字面量的计算结果作为单个参数传递给tag。但正如您在MDN示例中看到的那样,标记模板函数实际上会传递多个参数。如果函数通过模板字面量和其他值进行调用,则其内部调用方式肯定会有所不同,这将更加令人惊讶。那么,如果您真的想将模板字面量传递给函数,该如何调用函数呢?因此,引入新的语法似乎是有道理的。

这是 "普通" 函数调用的语法:

CallExpression : MemberExpression Arguments
CallExpression : CallExpression Arguments

最好还能添加一些关于参数如何进入函数的解释。 - choz
那么你的意思是模板字面量如何被“展开”成多个参数? - Felix Kling
是的,就像问题中所述。尽管传递的是“Hello ${a+b} world ${a*b}”,但strings具有{"Hello","world"},而values具有{a + b,a * b} - choz
如果你问为什么要这样做,我无法给你答案。它是这样做的,以便让人们轻松定义小型语言(DSL),用于从本地化到DOM模板化的各种用例。 - user663031
@torazaburo:我不是在谈论标记模板本身,而是语法决策。 - Felix Kling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接