ES6, ES2015 : Template strings

ES2015 add a new way to write better strings that will simplify our code: the template strings.

#Principle

To define a string in JavaScript, we have single quotes or double quotes. No one is really better than the other since you need to escape the quotes you are using in the string itself.

Template strings use back-tick (grave accent) to delimitate strings.

// ES5
var myString = 'I\'m a "string"';

// ES6
const myNewString = `I'm a "template string"`;

Nothing really awesome. So let's see the interesting new feature: interpolation.

#Interpolation

Now you can directly use expression in a template string if you use the new place holder syntax.: ${ expression }.

// ES5
var name = "world";
var myStrin = "Hello " + name; // => Hello world

// ES6
const newName = `developer`;
const myStrin = `Hello ${newName}`; // => Hello developer

Here we are just using a variable, but we can use any expression:

const x = 1;
const y = 2;
const result = `${x} + ${y} = ${x + y}`; // => 1 + 2 = 3

function square(num) {
  return num * num;
}
const result = `${square(5)}`; // => 25

This is what make template strings awesome.

#template strings are multi-lines capable

Another cool thing is that template strings handle multi-lines.

// ES5
var multiline = "foo \
                 bar \
                 baz";

var multiline2 = "foo";
multiline2 += "bar";
multiline2 += "baz";

// ES6
const multiline = `foo
                   bar
                   baz`;

Note keep in mind that spaces are as you write them, which can surprise you.

const str1 = `foo
bar`;

const str2 = `foo
             bar`;

str1 === str2; // => false

#Tagged template strings

Let's dive into another interesting feature of template strings. Tags are functions that will use just before the template string and they allow us to enhance the string result.

A tag take an array of "literals" (strings), and then all interpolated (evaluated) expressions that we can still modify.

function capitalizeVowels(strings, ...values) {
  function replaceVowels(string) {
    return string.replace(/[aeiou]/g, function(c) {
      return c.toUpperCase();
    });
  }

  let result = "";
  for (let i = 0; i < strings.length; ++i) {
    const nextValue = values[i] || "";
    result += replaceVowels(strings[i]);
    if (!parseInt(nextValue)) {
      result += replaceVowels(nextValue);
    } else {
      result += nextValue;
    }
  }
  return result;
}

capitalizeVowels`foo bar ?`; // => fOO bAr ?
const n = 42;
const c = "f";
const v = "o";
capitalizeVowels`foo ${n} bar ${c}${v}${v} ?`; // => fOO 42 bAr fOO ?

Here is an interesting example of tagged template strings to handle i18n for strings.

#String.raw

A new function has been added to String prototype that allows us display raw content so you can see unescaped characters:

String.raw`FOO\nbar`; // => FOO\\nbar

#Conclusion

When you will start to use template strings, you are likely going to like them. They are clearly really useful in a daily basis.

Almost all modern browser handle template strings today, as well as Babel and Traceur, so you do not hesitate to use template strings.