7

According to MDN, Tagged template literals can be used as follows:

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!"

In the example above, the function tag is called without using parentheses.

I expected it should be called like tag(`Hello`), but that passes the string resulting from the template literal as the argument for the strings parameter of the function.

What's this special feature of calling functions without parentheses but with parameter?

aWebDeveloper
  • 36,687
  • 39
  • 170
  • 242
  • Can you add a link to that example source? – JSelser Mar 23 '16 at 00:46
  • 4
    Tagged templates: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals . That's just how the syntax is. It is special in itself. – Felix Kling Mar 23 '16 at 00:47
  • This was the first time i saw a function being called without (). Initially thought it's some shorthand notation but a quick check said otherwise – aWebDeveloper Mar 23 '16 at 00:49
  • can someone care to explain why the -ve votes – aWebDeveloper Mar 23 '16 at 00:51
  • @aWebDeveloper: There are many ways to call functions, and not all of them involve parenthesis. Think of setters/getters as a trivial example. – Bergi Mar 23 '16 at 00:51
  • @Bergi sorry i dont know of any. care to give some links / more pointers i can read more on – aWebDeveloper Mar 23 '16 at 00:53
  • 1
    The `new` operator for example: `new Foo`. And of course there is `call` and `apply` (which are of course functions too, but you are not "using parenthesis" to call the function itself). – Felix Kling Mar 23 '16 at 00:57
  • I edited the question because it wasn't much clear for me. I think this is what you meant. – Oriol Mar 23 '16 at 01:12
  • Tagged template strings are explained right on the (MDN page about template strings)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals], and are discussed in any tutorial/post on the subject. –  Mar 23 '16 at 03:01
  • @aWebDeveloper There are a lot of documented examples of how to call functions without parenthesis at this SO link: Invoking a function without parentheses: http://stackoverflow.com/questions/35949554/invoking-a-function-without-parentheses/35949617#35949617 – Clomp Mar 25 '16 at 21:44

1 Answers1

6

What's this special feature of calling functions without parentheses?

This syntax for tagged templates is simply allowed by the the grammar:

MemberExpression : MemberExpression TemplateLiteral
CallExpression : CallExpression TemplateLiteral

These rules means that a MemberExpression or CallExpression followed by a TemplateLiteral is considered to be a function call. Additional note from the spec:

A tagged template is a function call where the arguments of the call are derived from a TemplateLiteral (12.2.9). The actual arguments include a template object (12.2.9.3) and the values produced by evaluating the expressions embedded within the TemplateLiteral.

If you are asking for why it was done this way, I cannot give you an answer.

However, if you think about it, the couldn't have just used "ordinary" function call syntax. tag(`...`) means that tag is passed a single argument, the result of evaluating the template literal. But as you can see in the example from MDN, tagged template functions actually get passed multiple arguments. It would certainly be more surprising if functions were called differently (internally) if they were passed a template literal vs if they were called with a different value. And then, how would call a function if you really wanted to pass a template literal to it?

Hence introducing a new syntax seems to make sense.


FWIW, this is the grammar for "ordinary" function calls:

CallExpression : MemberExpression Arguments
CallExpression : CallExpression Arguments
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • It'd be great to also add explanation how the parameters going into the functions. – choz Mar 23 '16 at 01:34
  • So you mean how the template literal is "exploded" into multiple arguments? – Felix Kling Mar 23 '16 at 01:35
  • Yeah, like as in question. How `strings` has `{"Hello", "world"}` and `values` has `{a + b, a * b}` despite of its passed by `Hello ${a+b} world ${a*b}`. – choz Mar 23 '16 at 01:38
  • *If you are asking for why it was done this way, I cannot give you an answer.* It was done this way to allow people to easily define mini-languages (DSLs) for use cases ranging from localization to DOM templating. –  Mar 23 '16 at 03:07
  • @torazaburo: I'm not talking about tagged templates itself, just the syntax decision. – Felix Kling Mar 23 '16 at 05:00