ES6 вызывающая функция с литералом шаблона, но без скобок

Согласно 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 параметр функции.

Что это за особенность вызова функций без скобок, но с параметром?

1 ответ

Решение

Что это за особенность вызова функций без скобок?

Этот синтаксис для теговых шаблонов просто разрешен грамматикой:

MemberExpression : MemberExpression TemplateLiteral
CallExpression : CallExpression TemplateLiteral

Эти правила означают, что MemberExpression или же CallExpression с последующим TemplateLiteral считается вызовом функции. Дополнительное примечание от спецификации:

Шаблон с тегами - это вызов функции, аргументы которого получены из TemplateLiteral ( 12.2.9). Фактические аргументы включают объект шаблона ( 12.2.9.3) и значения, полученные путем оценки выражений, встроенных в TemplateLiteral.

Если вы спрашиваете, почему это было сделано таким образом, я не могу дать вам ответ.

Однако, если подумать, нельзя было просто использовать "обычный" синтаксис вызова функции. tag(`...`) Значит это tag передается единственный аргумент, результат оценки литерала шаблона. Но, как вы можете видеть в примере из MDN, тегированные функции шаблона на самом деле получают несколько аргументов. Конечно, было бы более удивительно, если бы функции вызывались по-разному (внутренне), если им передавался литерал шаблона по сравнению с тем, если они вызывались с другим значением. И потом, как бы вызвать функцию, если вы действительно хотите передать ей литерал шаблона?

Следовательно, введение нового синтаксиса, кажется, имеет смысл.


FWIW, это грамматика для "обычных" вызовов функций:

CallExpression : MemberExpression Arguments
CallExpression : CallExpression Arguments
Другие вопросы по тегам