class: left, middle background-image: url(../../images/master-folie.png) .title[ ## Template and object literals
### Oleg Varaksin #### ovaraksin@googlemail.com ] --- # Template literals. __Template literals__ is a new feature in ES6 to make working with strings and string templates easier. You wrap your text in backticks (instead of double or single quotes) and you'll get the following features: - Multiline strings without hacks. - String formatting - the ability to substitute parts of the string for values contained in variables. This ability is also called string substitution. - Tagged templates - string tagging for safe HTML escaping, localisation and more. Basic syntax: ```js let message = `Hello world!`; console.log(message); // "Hello world!" console.log(typeof message); // "string" ``` The variable `message` contains a normal JavaScript string. If you want to use a backtick in your string, then just escape it with a backslash. ```js let message = `\`Hello\` world!`; ``` --- # Multiline strings (1/3). In ES5, when using double or single quotes, strings must be completely contained on a single line. There are workarounds for this shortcoming. Workarounds with backslash which is treated as a continuation, `join` and `\n`. ```js var message = "Multiline \ string"; console.log(message); // "Multiline string" ``` ```js var message = [ "Multiline ", "string" ].join("\n"); ``` ```js let message = "Multiline \n" + "string"; ``` --- # Multiline strings (2/3). In ES6, template literals make multiline strings easy because there's no special syntax. Just include a newline where you want. ```js let message = `Multiline string`; console.log(message); // "Multiline // string" ``` All whitespaces inside the backticks are parts of the string, so be careful with indentation. ```js let message = `Multiline string`; console.log(message); // "Multiline // string" ``` --- # Multiline strings (3/3). If making the text line up with proper indentation is important to you, then consider leaving nothing on the first line of a multiline template literal and then indenting after that. Example: ```js let html = `
Title
`.trim(); ``` --- # String substitution (1/3). Substitutions allow you to embed any valid JavaScript expression inside a template literal and output the result as part of the string. Substitutions are delimited by an opening `${` and a closing `}` that can have any JavaScript expression inside. ```js var name = "Max"; console.log(`Hello, ${name}!`); // => "Hello, Max!" ``` ```js var a = 10; var b = 10; console.log(`The number of JS MVC frameworks is ${2 * (a + b)} and not ${10 * (a + b)}.`); // => The number of JS frameworks is 40 and not 200. ``` __Note:__ A template literal can access any variable accessible in the scope in which it is defined. Attempting to use an undeclared variable in a template literal throws an error. --- # String substitution (2/3). The `${}` works fine with any kind of expression, including member expressions, function and method calls. ```js function fn() { return "I am a result. Rarr"; } console.log(`foo ${fn()} bar`); // => foo I am a result. Rarr bar. ``` ```js var user = { name: 'Max Mustermann' }; console.log(`Thanks for helping us, ${user.name.toUpperCase()}.`); // => "Thanks for helping us, MAX MUSTERMANN"; ``` --- # String substitution (3/3). Advanced example of building HTML structures. ```js var li = (obj) => `
${obj.label}
`; var ul = (arr) => `
${arr.map((obj) => li(obj)).join('\n')}
`; var arr = [ {url: "http://www.twitter.com", label: "Twitter"}, {url: "http://www.linkedin.com", label: "Linked In"}, {url: "http://www.facebook.com", label: "Facebook"} ]; document.getElementById('list').innerHTML = ul(arr); ``` This will generate the following output: ```js
Twitter
Linked In
Facebook
``` --- # Tagged templates (1/4). A _template tag_ performs a transformation on the template literal and returns the final string value. This tag is specified at the start of the template, just before the first backtick, e.g. ```js let message = tag`Hello world`; ``` In this example, `tag` is the template tag to apply to the `Hello world` template literal. A template tag is a function. - The first argument of this function is an array of all the plain strings (the stuff between any interpolated expressions). - Each subsequent argument is the interpreted value of each substitution. ```js function tag(literals, ...substitutions) { // return a string } ``` --- # Tagged templates (2/4). Simple example which outputs arguments. ```js function foo(strings, ...values) { console.log(strings); console.log(values); } var desc1 = "very"; var desc2 = "awesome"; foo`Everything is ${desc1} ${desc2}!`; // ["Everything is ", " ", "!"] // ["very", "awesome"] ``` __Using in real world:__ special processing for internationalization, localization, HTML escaping and more. --- # Tagged templates (3/4). Another example that mimics the default behavior of a template literal. ```js function passthru(literals, ...substitutions) { let result = ""; // run the loop only for the substitution count for (let i = 0; i < substitutions.length; i++) { result += literals[i]; result += substitutions[i]; } // add the last literal result += literals[literals.length - 1]; return result; } let count = 10, price = 0.25, message = passthru`${count} items cost $${(count * price)}.`; console.log(message); // "10 items cost $2.50." ``` --- # Tagged templates (4/4). 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 of the first argument. Example: ```js function showraw(strings, ...values) { console.log(strings); console.log(strings.raw); } showraw`Hello\nWorld`; // [ "Hello // World" ] // [ "Hello\nWorld" ] ``` The raw version of the value preserves the raw escaped `\n` sequence (the `\` and the `n` are separate characters). __Note:__ ES6 comes with a built-in function `String.raw(...)` that can be used to access the raw string. --- # Object literal syntax extensions (1/4). __ES5.__ Object creation leads to duplications when the names are the same as the function parameter names. ```js function createPerson(name, age) { return { name: name, age: age }; } ``` __ES6.__ Property initializer shorthand: when an object property name is the same as the local variable name, you can simply include the name without a colon and value. ```js function createPerson(name, age) { return { name, age }; } ``` --- # Object literal syntax extensions (2/4). __ES5.__ You must specify a name and then the full function definition to add a method to an object. ```js var person = { name: "Nicholas", sayName: function() { console.log(this.name); } }; ``` __ES6.__ The colon and the `function` keyword can be eliminated. ```js var person = { name: "Nicholas", sayName() { console.log(this.name); } }; ``` --- # Object literal syntax extensions (3/4). In __ES6__, computed property names can be used in object literals within square brackets. ```js var suffix = " name"; var lastName = "last name"; var person = { ["first" + suffix]: "Max", [lastName]: "Mustermann" }; console.log(person["first" + suffix]); // "Max" console.log(person[lastName]); // "Mustermann" ``` It is not possible in __ES5__ where only constants may be used in object literals. --- # Object literal syntax extensions (4/4). In __ES6__, the duplicate property check was removed. There is no syntax error as in __ES5__ when two and more properties have the same names. Instead, the last property of the given name becomes the property's actual value. ```js var person = { name: "Max", name: "Greg" }; console.log(person.name); // "Greg" ``` --- class: center, middle, inverse # That's all folks, thanks for your attention! .back[[Back to the homepage](http://ova2.github.io/es6-presentations/)] Slideshow created with [remark](https://github.com/gnab/remark)