Explain the template string _ Basics in JavaScript ES6

Source: Internet
Author: User
Tags data structures i18n

The introduction of a new string literal-template string in ES6, in addition to using inverted quotation marks ('), means that they do not appear to be any different from ordinary strings. In the simplest case, they are ordinary strings:

Context.filltext (' Ceci n ' est pas une cha?ne. ', x, y);
 
Context.filltext (' Ceci n ' est pas une cha?ne. ', x, y);

It is called a template string because the template string is a simple string interpolation attribute for JS, which means that the value of JS can be conveniently inserted into the string.

In many places, you can use the template string to see this humble error message:

function authorize (user, action) {
 if (!user.hasprivilege (action)) {
  throw new Error (
   ' user ${user.name} is Not authorized to do ${action}. '}
 
function authorize (user, action) {
 if (!user.hasprivilege (action)) {
  throw new Error (
   ' user ${user.name is not authorized to do ${action}. '}

In the code above, ${user.name} and ${action} are called template placeholders, and JavaScript inserts the value of the User.Name and action into the corresponding position, and then generates a "user Jorendorff is not" autho like this String rized to do hockey.

Now we see a more elegant syntax than the + operator, and here are some of the features you'd expect:

Template placeholders can be any JavaScript expression, so function calls and arithmetic are legitimate. (Even you can nest another template string in a template string.) )
If a value is not a string, it is converted to a string. For example, if the action is an object, the. toString () of the object is invoked to convert it to a string.
If you want to use an inverted quote in a template string, you need to use a backslash to escape it.
Similarly, if you want to output ${in a template string, you also need to use a backslash to escape it: \${or $\{.
Template strings can span multiple lines:

$ ("#warning"). html ('
  
 

All spaces, newline, and indents in the template string are output to the result string as-is.

Let's look at what the template strings can't do:

Special characters are not automatically escaped, and in order to avoid cross-site scripting vulnerabilities, you still need to be careful with untrusted data, as with normal strings.
cannot be used in conjunction with internationalized libraries, and does not deal with numbers, dates, etc. in special language formats.
is not a substitute for a template engine (such as mustache or nunjucks). The template string has no syntax for handling loops-you cannot build a table (table) out of an array.

To address these limitations, ES6 provides another template string-label template for developers and library designers.

The syntax for a label template is simple, simply by introducing a label before the opening inverted quotation mark. Look at the first example: saferhtml, we want to use this tag template to solve the first limitation above: automatically escape special characters.

It should be noted that the Saferhtml method is not provided by the ES6 standard library, and we need to implement it ourselves:

var message =
 saferhtml ' <p>${bonk.sender} has sent for you a bonk.</p> ';
 
var message =
 saferhtml ' <p>${bonk.sender} has sent for you a bonk.</p> ';

The saferhtml tag here is a single identifier, and the label can be a property, such as a saferhtml.escape, or even a method call: Saferhtml.escape ({unicodecontrolcharacters:false}). To be exact, any ES6 member expression or invocation expression can be used as a label.

As you can see, the template string is just the syntactic sugar of string concatenation, and the label template is a completely different thing: a function call.

So the code above is equivalent to:

var message =
 saferhtml (TemplateData, bonk.sender);
 
var message =
 saferhtml (TemplateData, Bonk.sender);

Where TemplateData is an immutable string array, generated by the JS engine based on the source template string, where the array contains two elements, because the template string is delimited by a placeholder containing two strings, so TemplateData will be: Object.freeze (["<p>", "has sent you a bonk.</p>"]

(In fact, there is another attribute on the TemplateData: Templatedata.raw, which is not discussed in depth.) The value of this property is also an array that contains all the string parts in the label template, but the string contains an escape sequence that looks more like a string in the source code, such as \ n. ES6 's built-in label String.raw will use these strings. )

This allows the Saferhtml method to parse the two strings at will, and there is a substitution in N.

As you continue to read the money, you may be struggling to think about how to implement the Saferhtml method.

The following is an implementation (GIST):

function saferhtml (TemplateData) {
 var s = templatedata[0];
 for (var i = 1; i < arguments.length i++) {
  var arg = String (Arguments[i]);

  Escape special characters in the substitution.
  S + + arg.replace (/&/g, "&")
      . Replace (/</g, "<")
      . Replace (/>/g, ">");

  Don ' t escape special characters in the template.
  s + + templatedata[i];
 }
 return s;
}
 
function saferhtml (TemplateData) {
 var s = templatedata[0];
 for (var i = 1; i < arguments.length i++) {
  var arg = String (Arguments[i]);
 
  Escape special characters in the substitution.
  S + + arg.replace (/&/g, "&")
      . Replace (/</g, "<")
      . Replace (/>/g, ">");
 
  Don ' t escape special characters in the template.
  s + + templatedata[i];
 }
 return s;
}

With the above method, even with a malicious user name, the user is safe.

A simple example is not enough to illustrate the flexibility of a label template, so let's revisit the limitations of the template strings listed above to see what else we can do.

The template string does not automatically escape special characters, but we can solve the problem with the label template, in fact we can also write saferhtml this method better. From a security standpoint, this saferhtml is very fragile. In HTML, different places need to be escaped in different ways, saferhtml not. With a little thought, we can implement a more flexible saferhtml method that will be able to escape any HTML in the TemplateData, knowing which placeholder is pure HTML, which is the attribute of the element, which requires a ' and ' escape, and which is the URL's query string , which requires the escaping method of the URL rather than the escaping of the HTML, and so on. This may seem far-fetched because of the low efficiency of HTML escapes. Sinyun Yes, the string of the label template is constant, saferhtml can cache the string that has been escaped, thereby increasing the efficiency.
The template string does not have a built-in internationalization feature, but with the label template, we can add the attribute. Jack Hsu's article details the implementation process, looking at the following example:

i18n ' Hello ${name}, you have ${amount}:c (CAD) in your bank account. '
//=> Hallo Bob, Sie haben 1.234,56 $CA auf Ih REM Bankkonto.




i18n ' Hello ${name}, you have ${amount}:c (CAD) in your bank account. '
//=> Hallo Bob, Sie haben 1.234,56 $CA auf Ih REM Bankkonto.

The name and amount in the example above are well understood, the JS engine will be replaced with the corresponding string, but there is another placeholder that has not been seen:: C (CAD), which will be processed by the i18n tag, from the i18n documentation:: C (CAD) indicates that amount is a Canadian dollar currency value.

Template strings cannot replace template engines such as mustache and nunjucks, partly because the template strings do not support loops and conditional statements. We can write a tag to implement this type of functionality:

Purely hypothetical template language based on
//ES6 tagged templates.
var libraryhtml = Hashtemplate '
 <ul>
  #for book in ${mybooks}
   <li><i>#{book.title}</ I> by #{book.author}</li>
  #end
 </ul>
';

 
Purely hypothetical template language based on
//ES6 tagged templates.
var libraryhtml = Hashtemplate '
 <ul>
  #for book in ${mybooks}
   <li><i>#{book.title} </i> by #{book.author}</li>
  #end
 </ul>
';

There is more flexibility than this, and it is worth noting that the parameters of the label function are not automatically converted to strings, arguments can be of any type, and the return value is the same. Tag templates can even do without strings, you can use custom tags to create regular expressions, DOM trees, pictures, Promise that represent the entire asynchronous process, JS data structures, GL shaders ...

The label template allows the library designer to create powerful domain-specific languages. These languages may not look like JS, but they can be seamlessly embedded in JS and interact with the rest of the language. By the way, I haven't seen a similar feature in other languages, and I don't know what this feature says about us, but the possibilities are very exciting.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.