This article is part of a web development series from Microsoft. Thank you for supporting the partners who make SitePoint possible.
JavaScript template literals, new to ES6, provide a powerful new tool for doing everything from extending strings across lines to building powerful HTML and XML generators. This article will cover the big changes that template literals bring to JavaScript, including the backtick character, expressions in templates, template functions, and building more complex XML/HTML templates.
The Backtick Character
You've no doubt run into this situation: you have a line of text, maybe HTML, that extends over several lines. How to put those multiple lines in HTML? It is possible to use the + operator to join strings across multiples lines (provided you enclose them in quotes) or even just append the line with the backslash character ("\"
). Those work. They are also awkward, error prone, and ugly.
ES6 introduces another way to extend strings across a single line, using the back-tick character (`
). At its simplest, this solves two issues with one throw - the aforementioned one of letting you have one string with embedded carriage returns, and the not to be sneezed at ability to incorporate both single and double quotes in a string without having to escape them.
Consider this code and observe what it generates below:
`"This isn't just another quote," Ada said. "It's a magical quote.";
"I'm not quite sure what you mean."
Clive settled onto the couch, one foot over the armchair rest, eyeing her dubiously.
"Consider this - if I have to write a quote in code normally, say something like 'This is a weird quote.' \
then I have to spend a lot of time using escape characters like \\" and \\', and they can make for real \
legibility problems. With a magic quote, though, they just go away!"
"Really?"
"You do have to double escape your escape characters, however. \\n will still get interpreted as an hard \
carriage return, but \\\\n will give you the slash followed by the letter 'n'."
`
console.log(quote)
This generates the output:
"This isn't just another quote," Ada said. "It's a magical quote."
"I'm not quite sure what you mean."
Clive settled onto the couch, one foot over the armchair rest, eyeing her dubiously.
"Consider this - if I have to write a quote in code normally, say something like 'This is a weird quote.' then I have to spend a lot of time using escape characters like \"
and \'
, and they can make for real legibility problems. With a magic quote, though, they just go away!"
"Really?"
"You do have to double escape your escape characters, however. \n
will still get interpreted as a hard carriage return, but \\n
will give you the slash followed by the letter 'n'
."
The effect is instantaneous here - in effect, the backtick (or more accurately, the template literal operator) performs a conversion of carriage returns, tabs and quotes into their respective normal string representations. This not only handles the pain of dealing with apostrophes in conversational text (as demonstrated above), but it also makes the corresponding code considerably easier to read.
Note as well that the terminating backspace character is still recognized within templates, which can be very useful when you have text that runs longer than your available screen-width. The difference between a regular string and a template string is that in the former you need to escape every line, while in the latter you need only escape the overly long strings.
If your string contains a number of escaped characters (such as the newline or tab character) and you don't want to get caught up in counting slashes, you can also use the String.raw` literal form.
String.raw`The sequence \t puts a tab into a template literal`
"The sequence \t puts a tab into a template literal."
Evaluating Expressions in Template Strings
Template literals also solve another problem: they can evaluate variables within the string. The ${expr}
construct, when used within a template literal, will evaluate the expression and incorporate this into a string itself.
var name = "Ada";
var vocation = "steampunk programmer";
varpcAssert = `${name} is a ${vocation}.`;
console.log(pcAssert)
// "Ada is a steampunk programmer."
Using a template literal as a...template
In the example below, the variable name and vocation are both predefined, and the ${}
expressions then replace the variables with their associated values. In a similar vein, you can both evaluate content and use object references within these expressions:
Template Functions
At this stage, template literals are beginning to look interesting. You can create a complex template literal that can reduce the amount of time embedded such content into a string. However, template literals begin to come into their own when combined with functions which produce the same output.
Note that this can also be simplified somewhat by using ES6 arrow notation:
var pounds = (amount) => (
amount.toLocaleString("en-UK", {
style:'currency',
currency:'GBP'
})
);
varpronounUCase = (gender) => (gender == 'female') ? 'She' : 'He';
var describe = (obj) => (
`${obj.name} is a ${obj.vocation}.\
${pronounUCase(obj.gender)} has ${pounds(obj.wealth)} \ in the bank.`
);
var person = {
name: "Ada",
vocation: "steampunk programmer",
gender: "female",
wealth: 24025
};
console.log(describe(person))
// "Ada is a steampunk programmer. She has £24,025.00 in the bank."
If the goal was to make a method on person
, you'd be better off going with the more traditional functional notation, as the this keyword is not defined within an arrow function:
var person = {
name: "Ada",
vocation: "steampunk programmer",
gender: "female",
wealth: 24025,
pounds: (amount) => (amount.toLocaleString("en-UK", {
style: 'currency',
currency:'GBP'
})
),
pronoun: (gender) => (gender === "female") ? "She" : "He",
toString: function(){
varself = this;
return (`${self.name} is a ${self.vocation}.\
${self.pronoun(self.gender)} has ${self.pounds(self.wealth)} \
in the bank.`
)
}
};
console.log(""+ person)
// "Ada is a steampunk programmer.She has £24,025.00 in the bank."
Creating a toString() Method with a Template
The use of the toString() method should be noted, as toString()
is automatically called whenever an object is converted into a string without having to be explicitly invoked. This means that while person
itself will always give the object, "" + person
will return the templated string as output, making toString()
useful for defining on classes and prototyped objects.
Continue reading %ES6 Template Literals: Techniques and Tools%
by Kurt Cagle via SitePoint
No comments:
Post a Comment