Key Takeaways
- ES6 (ECMAScript 6) is the future of JavaScript and brings many features that help the language stay competitive with the needs of the modern web.
- ES6 introduces Template Strings, a new way to handle strings in JavaScript. Template Strings use the backtick (`) as a new string delimiter, which allows for string expression substitution and multi-line strings.
- Template Strings can be prepended with a tag, which is the name of a function that is called and gets the string as a parameter. This can be used, for example, to encode the resulting string for URLs.
- Template Strings are supported by most modern browsers, but for older browsers, ES6 can be transpiled to ES5. A feature test for Template String support can be performed using a library or with specific code.
This article is part of a web development series from Microsoft. Thank you for supporting the partners who make SitePoint possible.
ES6 is the future of JavaScript and it is already here. It is a finished specification, and it brings a lot of features a language requires to stay competitive with the needs of the web of now. Not everything in ES6 is for you and in this little series of posts I will show features that are very handy and already usable. If you look at JavaScript code I’ve written you will find that I always use single quotes to define strings instead of double quotes. JavaScript is OK with either, the following two examples do exactly the same thing:
var animal = "cow";
var animal = 'cow';
The reason why I prefer single quotes is that, first of all, it makes it easier to assemble HTML strings with properly quoted attributes that way:
// with single quotes, there's no need to
// escape the quotes around the class value
var but = '<button class="big">Save</button>';
// this is a syntax error:
var but = "<button class="big">Save</button>";
// this works:
var but = "<button class=\"big\">Save</button>";
The only time you need to escape now is when you use a single quote in your HTML, which should be a very rare occasion. The only thing I can think of is inline JavaScript or CSS, which means you are very likely to do something shady or desperate to your markup. Even in your texts, you are probably better off to not use a single quote but the typographically more pleasing.
Aside: Of course, HTML is forgiving enough to omit the quotes or to use single quotes around an attribute, but I prefer to create readable markup for humans rather than relying on the forgiveness of a parser. We made the HTML5 parser forgiving because people wrote terrible markup in the past, not as an excuse to keep doing so.
I’ve suffered enough in the DHTML days of document.write to create a document inside a frameset in a new popup window and other abominations to not want to use the escape character ever again. At times, we needed triple ones, and that was even before we had colour coding in our editors. It was a mess.
Expression Substitution in Strings?
Another reason why I prefer single quotes is that I wrote a lot of PHP in my time for very large web sites where performance mattered a lot. In PHP, there is a difference between single and double quotes. Single quoted strings don’t have any substitution in them, double quoted ones have. That meant back in the days of PHP 3 and 4 that using single quotes was much faster as the parser doesn’t have to go through the string to substitute values. Here is an example what that means:
<?php
$animal = 'cow';
$sound = 'moo';
echo 'The animal is $animal and its sound is $sound';
// => The animal is $animal and its sound is $sound
echo "The animal is $animal and its sound is $sound";
// => The animal is cow and its sound is moo
?>
JavaScript didn’t have this substitution, which is why we had to concatenate strings to achieve the same result. This is pretty unwieldy, as you need to jump in and out of quotes all the time.
var animal = 'cow';
var sound = 'moo';
alert('The animal is ' + animal + ' and its sound is ' + sound);
// => "The animal is cow and its sound is moo"
Multi-line Mess
This gets really messy with longer and more complex strings and especially when we assemble a lot of HTML. And, most likely you will sooner or later end up with your linting tool complaining about trailing whitespace after a + at the end of a line. This is based on the issue that JavaScript has no multi-line strings:
// this doesn't work
var list = '<ul>
<li>Buy Milk</li>
<li>Be kind to Pandas</li>
<li>Forget about Dre</li>
</ul>';
// This does, but urgh…
var list = '<ul>\
<li>Buy Milk</li>\
<li>Be kind to Pandas</li>\
<li>Forget about Dre</li>\
</ul>';
// This is the most common way, and urgh, too…
var list = '<ul>' +
' <li>Buy Milk</li>' +
' <li>Be kind to Pandas</li>' +
' <li>Forget about Dre</li>' +
'</ul>';
Client-side Templating Solutions
In order to work around the mess that is string handling and concatenation in JavaScript, we did what we always do – we write a library. There are many HTML templating libraries with Mustache.js probably having been the seminal one. All of these follow an own – non standardized – syntax and work in that frame of mind. It’s a bit like saying that you write your content in markdown and then realizing that there are many different ideas of what “markdown” means.Enter Template Strings
With the advent of ES6 and its standardization we now can rejoice as JavaScript has now a new kid on the block when it comes to handling strings: Template Strings. The support of template strings in current browsers is encouraging: Chrome 44+, Firefox 38+, Microsoft Edge and Webkit are all on board. Safari, sadly enough, is not, but it’ll get there. The genius of template strings is that it uses a new string delimiter, which isn’t in use either in HTML nor in normal texts: the backtick (`). Using this one we now have string expression substitution in JavaScript:
var animal = 'cow';
var sound = 'moo';
alert(`The animal is ${animal} and its sound is ${sound}`);
// => "The animal is cow and its sound is moo"
The ${}
construct can take any JavaScript expression that returns a value, you can for example do calculations, or access properties of an object:
var out = `ten times two totally is ${ 10 * 2 }`;
// => "ten times two totally is 20"
var animal = {
name: 'cow',
ilk: 'bovine',
front: 'moo',
back: 'milk',
}
alert(`
The ${animal.name} is of the
${animal.ilk} ilk,
one end is for the ${animal.front},
the other for the ${animal.back}
`);
// =>
/*
The cow is of the
bovine ilk,
one end is for the moo,
the other for the milk
*/
That last example also shows you that multi line strings are not an issue at all any longer.
Tagged Templates
Another thing you can do with template strings is prepend them with a tag, which is the name of a function that is called and gets the string as a parameter. For example, you could encode the resulting string for URLs without having to resort to the horridly namedencodeURIComponent
all the time.
function urlify (str) {
return encodeURIComponent(str);
}
urlify `http://beedogs.com`;
// => "http%3A%2F%2Fbeedogs.com"
urlify `woah$£$%£^$"`;
// => "woah%24%C2%A3%24%25%C2%A3%5E%24%22"
// nesting also works:
var str = `foo ${urlify `&&`} bar`;
// => "foo %26%26 bar"
This works, but relies on implicit array-to-string coercion. The parameter sent to the function is not a string, but an array of strings and values. If used the way I show here, it gets converted to a string for convenience, but the correct way is to access the array members directly.
Retrieving Strings and Values from a Template String
Inside the tag function you can not only get the full string but also its parts.
function tag (strings, values) {
console.log(strings);
console.log(values);
console.log(strings[1]);
}
tag `you ${3+4} it`;
/* =>
Array [ "you ", " it" ]
7
it
*/
There is also an array of the raw strings provided to you, which means that you get all the characters in the string, including control characters. Say, for example, you add a line break with \n. You will get the double whitespace in the string, but the \n characters in the raw strings:
function tag (strings, values) {
console.log(strings);
console.log(values);
console.log(strings[1]);
console.log(strings.raw[1]);
}
tag `you ${3+4} \nit`;
/* =>
Array [ "you ", " it" ]
7
it
\nit
*/
Conclusion
Template strings are one of those nifty little wins in ES6 that can be used right now. If you have to support older browsers, you can of course transpile your ES6 to ES5; you can do a feature test for template string support using a library like featuretests.io or with the following code:
var templatestrings = false;
try {
new Function( "`{2+2}`" );
templatestrings = true;
} catch (err) {
templatestrings = false;
}
if (templatestrings) {
// …
}
More articles on template strings:
- Understanding ECMAScript 6: Template Strings
- Getting Literal With ES6 Template Strings
- ES6 In Depth: Template strings
- New string features in ECMAScript 6
- Understanding ES6: Template Strings
- HTML templating with ES6 template strings
More hands-on with JavaScript
This article is part of the web development series from Microsoft tech evangelists on practical JavaScript learning, open source projects, and interoperability best practices including Microsoft Edge browser and the new EdgeHTML rendering engine. We encourage you to test across browsers and devices including Microsoft Edge – the default browser for Windows 10 – with free tools on dev.modern.IE:- Scan your site for out-of-date libraries, layout issues, and accessibility
- Use virtual machines for Mac, Linux, and Windows
- Remotely test for Microsoft Edge on your own device
- Coding Lab on GitHub: Cross-browser testing and best practices
- Microsoft Edge Web Summit 2015 (what to expect with the new browser, new supported web platform standards, and guest speakers from the JavaScript community)
- Woah, I can test Edge & IE on a Mac & Linux! (from Rey Bango)
- Advancing JavaScript without Breaking the Web (from Christian Heilmann)
- The Edge Rendering Engine that makes the Web just work (from Jacob Rossi)
- Unleash 3D rendering with WebGL (from David Catuhe including the vorlon.JS and babylonJS projects)
- Hosted web apps and web platform innovations (from Kevin Hill and Kiril Seksenov including the manifold.JS project)
Frequently Asked Questions about ES6 Template Strings
What are the benefits of using ES6 template strings over traditional string concatenation?
ES6 template strings offer several advantages over traditional string concatenation. Firstly, they provide a more readable and concise syntax. You don’t need to use the ‘+’ operator to concatenate strings, which can make your code cleaner and easier to understand. Secondly, template strings support multiline strings without needing to use escape characters or concatenation, which can be very useful when working with large strings. Lastly, template strings allow you to embed expressions within the string itself, which can be evaluated and included in the output string. This can be a powerful tool for dynamically generating strings.
Can I use template strings with all JavaScript data types?
Yes, you can use template strings with all JavaScript data types. When you include an expression within a template string, it will be converted to a string before being included in the output. This means you can include numbers, booleans, objects, arrays, and even other strings within your template strings.
Are there any browser compatibility issues with ES6 template strings?
Most modern browsers fully support ES6 template strings. However, they are not supported in Internet Explorer. If you need to support older browsers, you may need to use a transpiler like Babel to convert your ES6 code into ES5.
How can I include a variable within a template string?
To include a variable within a template string, you simply need to wrap it in curly braces and precede it with a dollar sign, like this: ${variable}
. The variable will be evaluated and its value will be included in the output string.
Can I perform operations within a template string?
Yes, you can perform operations within a template string. Any valid JavaScript expression can be included within the curly braces in a template string. This includes arithmetic operations, function calls, and even ternary expressions.
How do I create multiline strings with template strings?
Creating multiline strings with template strings is straightforward. You simply need to include a line break in your string, and it will be preserved in the output. This is a significant improvement over traditional strings, which required you to use the ‘\n’ escape character to create line breaks.
Can I nest template strings within each other?
Yes, you can nest template strings within each other. This can be useful when you need to create complex strings with multiple levels of interpolation.
Are there any performance implications of using template strings?
In general, the performance of template strings is comparable to that of traditional strings. However, if you’re performing a large number of string concatenations, traditional strings may be slightly faster. That being said, the readability and convenience of template strings often outweighs any minor performance differences.
Can I use template strings in Node.js?
Yes, you can use template strings in Node.js. They are fully supported in Node.js versions 4.0.0 and above.
How do I escape special characters in a template string?
To escape special characters in a template string, you can use the backslash (”) character, just like with traditional strings. For example, to include a dollar sign in your string, you would write `=.
Chris Heilmann is a Senior Program Manager at Microsoft and literally wrote the handbook on developer evangelism. He spends a lot of time speaking at conferences, blogging and helping people understand and make others understand technology better. You can follow him on Twitter and read his blog.