What is “Tagged Template Literals”, or “Tagged Templates”?
Let’s take a look at a simplified version of MDN’s very confusing example [1].
var a = 1, b = 2, c = 3; function tag(strings, ...values) { return "Bazinga!"; } tag`${a} Hello ${b} world ${c}`; // "Bazinga!"
To read this, first we need to understand the ...values
part. The dots before the last parameter means “all the parameters after this point”. Which, is a genuine array. This is part of the new power that comes with ES6 [2]. No need to do the awkward Array.prototype.slice.call(arguments)
dance to grab the arguments array any more. Yay.
Now, we can say that what this piece of code is trying to convey is:
- with
strings
, we get an array of string pieces that we passed in when calling it:["", " Hello ", " world ", ""]
- with
values
, we get an array of value pieces with the call as well:[1, 2, 3]
You might have noticed that the ${b}
part is no where to be seen in the strings
array. Yes, only ${}
s at the start and end of a string would be counted in here.
But what’s the use of getting the two arrays?
Well, we can essentially return anything we want it to. A string, sure. That can be useful for auto-escaping, formatting, localisation [3] and in general, more complex substitutions [4]. An object, no problem. Depending on our need, we can even return a function based on the string, as did the POST request example here [5].
There’s also a built in tagged template in ES6 called String.raw
[6], which would keep all the escape characters, white spaces, tags and new lines inside of ``
as is:
String.raw`Hi\n!`; // 'Hi\\n!', the character after 'Hi' is not a newline character, // '\' and 'n' are two characters.
So if you ever need to do complicated string manipulations again, consider Tagged Templates.