I have the following code for ECMAScript 6 template literals:
let person = {name: 'John Smith'}; let tpl = `My name is ${person.name}.`; let MyVar = "My name is " + person.name + "."; console.log("template literal= " + tpl); console.log("my variable = " + MyVar);
The output is as follows:
template literal= My name is John Smith. my variable = My name is John Smith.
This is the fiddle.
I tried searching for the exact difference, but I couldn't find it, What is the difference between the following two statements?
let tpl = `My name is ${person.name}.`;
And
let MyVar = "My name is "+ person.name+".";
I am already able to get the string MyVar
concatenated with person.name
here, so what would be the scenario to use the template literal in?
Variable and expression substitutions At this point, a template literal is just like a better version of a regular JavaScript string. The big difference between a template literal and a regular string is substitutions. The substitutions allow you to embed variables and expressions in a string.
popular templaters like mustache/underscore/handlebars are dozens to hundreds of times slower than concatenation is or template literals will be. Theoretical speaking (unless the JS is compiled), template literals would be slower since the 'string' needs to be parsed regardless of placeholder existence.
Template literals are a new feature introduced in ECMAScript 2015/ ES6. It provides an easy way to create multiline strings and perform string interpolation. Template literals are the string literals and allow embedded expressions. Before ES6, template literals were called as template strings.
The speed of string literals in JavaScript He said backtick literals are less performant (in other words, slower) because they need to processed. In other words, the variable interpolation that we want from backtick literals are an Achilles' heel — processing the template literals slows performance.
If you are using template literals only with placeholders (e.g. `Hello ${person.name}`
) like in the question's example, then the result is the same as just concatenating strings. Subjectively it looks better and is easier to read, especially for multi-line strings or strings containing both '
and "
since you don't have to escape those characters any more.
Readability is a great feature, but the most interesting thing about templates are Tagged template literals:
let person = {name: 'John Smith'}; let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1]; tag `My name is ${person.name}!` // Output: My name is JOHN SMITH!
In the third line of this example, a function named tag
is called. The content of the template string is split into multiple variables, that you can access in the arguments of the tag
function: literal sections (in this example the value of strArr[0]
is My name is
and the value of strArr[1]
is !
) and substitutions (John Smith
). The template literal will be evaluated to whatever the tag
function returns.
The ECMAScript wiki lists some possible use cases, like automatically escaping or encoding input, or localization. You could create a tag function named msg
that looks up the literal parts like My name is
and substitutes them with translations into the current locale's language, for example into German:
console.log(msg`My name is ${person.name}.`) // Output: Mein Name ist John Smith.
The value returned by the tag function doesn't even have to be a string. You could create a tag function named $
which evaluates the string and uses it as a query selector to return a collection of DOM nodes, like in this example:
$`a.${className}[href=~'//${domain}/']`
ES6 comes up with a new type of string literal, using the `
back-tick as the delimiter. These literals do allow basic string interpolation expressions to be embedded, which are then automatically parsed and evaluated.
let actor = {name: 'RajiniKanth', age: 68}; let oldWayStr = "<p>My name is " + actor.name + ",</p>\n" + "<p>I am " + actor.age + " old</p>\n"; let newWayHtmlStr = `<p>My name is ${actor.name},</p> <p>I am ${actor.age} old</p>`; console.log(oldWayStr); console.log(newWayHtmlStr);
As you can see, we used the ..`` around a series of characters, which are interpreted as a string literal, but any expressions of the form ${..}
are parsed and evaluated inline immediately.
One really nice benefit of interpolated string literals is they are allowed to split across multiple lines:
var Actor = {"name" : "RajiniKanth"}; var text = `Now is the time for all good men like ${Actor.name} to come to the aid of their country!`; console.log( text ); // Now is the time for all good men // to come to the aid of their // country!
Interpolated Expressions
Any valid expression is allowed to appear inside ${..}
in an interpolated string lit‐ eral
, including function calls, inline function expression calls, and even other interpo‐ lated string literals
!
function upper(s) { return s.toUpperCase(); } var who = "reader" var text = `A very ${upper( "warm" )} welcome to all of you ${upper( `${who}s` )}!`; console.log( text ); // A very WARM welcome // to all of you READERS!
Here, the inner ${who}s`` interpolated string literal was a little bit nicer convenience for us when combining the who variable with the "s"
string, as opposed to who + "s". Also to keep an note is an interpolated string literal is just lexically scoped
where it appears, not dynamically scoped
in any way:
function foo(str) { var name = "foo"; console.log( str ); } function bar() { var name = "bar"; foo( `Hello from ${name}!` ); } var name = "global"; bar(); // "Hello from bar!"
Using the template literal
for the HTML is definitely more readable by reducing the annoyance.
The plain old way:
'<div class="' + className + '">' + '<p>' + content + '</p>' + '<a href="' + link + '">Let\'s go</a>' '</div>';
With ES6:
`<div class="${className}"> <p>${content}</p> <a href="${link}">Let's go</a> </div>`
Tagged Template Literals
We can also tag a template
string, when a template
string is tagged, the literals
and substitutions are passed to function which returns the resulting value.
function myTaggedLiteral(strings) { console.log(strings); } myTaggedLiteral`test`; //["test"] function myTaggedLiteral(strings,value,value2) { console.log(strings,value, value2); } let someText = 'Neat'; myTaggedLiteral`test ${someText} ${2 + 3}`; // ["test ", " ", ""] // "Neat" // 5
We can use the spread
operator here to pass multiple values. The first argument — we called it strings — is an array of all the plain strings (the stuff between any interpolated expressions).
we then gather up all subsequent arguments into an array called values using the ... gather/rest operator
, though you could of course have left them as individual named parameters following the strings parameter like we did above (value1, value2 etc)
.
function myTaggedLiteral(strings,...values) { console.log(strings); console.log(values); } let someText = 'Neat'; myTaggedLiteral`test ${someText} ${2 + 3}`; // ["test ", " ", ""] // ["Neat", 5]
The argument(s)
gathered into our values array are the results of the already evaluated interpolation expressions found in the string literal. A tagged string literal
is like a processing step after the interpolations are evaluated but before the final string value is compiled, allowing you more control over generating the string from the literal. Let's look at an example of creating a re-usable templates
.
const Actor = { name: "RajiniKanth", store: "Landmark" } const ActorTemplate = templater`<article> <h3>${'name'} is a Actor</h3> <p>You can find his movies at ${'store'}.</p> </article>`; function templater(strings, ...keys) { return function(data) { let temp = strings.slice(); keys.forEach((key, i) => { temp[i] = temp[i] + data[key]; }); return temp.join(''); } }; const myTemplate = ActorTemplate(Actor); console.log(myTemplate);
Raw Strings
Our tag functions receive a first argument we called strings
, which is an array
. But there’s an additional bit of data included: the raw unprocessed versions of all the strings. You can access those raw string values using the .raw
property, like this:
function showraw(strings, ...values) { console.log( strings ); console.log( strings.raw ); } showraw`Hello\nWorld`;
As you can see, the raw
version of the string preserves the escaped \n sequence, while the processed version of the string treats it like an unescaped real new-line. ES6 comes with a built-in function that can be used as a string literal tag: String.raw(..)
. It simply passes through the raw versions of the strings
:
console.log( `Hello\nWorld` ); /* "Hello World" */ console.log( String.raw`Hello\nWorld` ); // "Hello\nWorld"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With