Author Jason Orendorff GitHub home Page Https://github.com/jorendorff
Anti-apostrophe (') basics
ES6 introduces a new type of string literal syntax, which we call template strings. In addition to using the anti-apostrophe character ' instead of the quotation marks ' or ' for ordinary strings, they appear to be no more than normal strings. In the simplest case, they are consistent with the performance of ordinary strings:
Context.filltext (' Ceci n ' est pas une chaîne. ', x, y);
But we didn't say, "It's just a normal string that's surrounded by anti-apostrophes." The template string name is rational, it provides JavaScript with a simple string interpolation function, from then on, you can in a more beautiful, more convenient way to interpolate into the string.
Template strings are used in thousands of ways, but the most important thing to me is to apply them to an inconspicuous error message:
function authorize (user, action) { if (!user.hasprivilege (action)) { throw new Error ( ' user ${user.name} ${action} is not authorized to perform the operation. `); }}
In this example, ${user.name} and ${action} are called template placeholders, and JavaScript inserts the values of User.Name and action into the resulting string, for example: User Jorendorff is not authorized to play hockey. (It's true that I haven't got a hockey license yet.) )
So far, what we've learned is just more elegant syntax than the + operator, and here are some of the features you might expect:
- The code in the template placeholder can be any javascript expression, so function calls, arithmetic operations, and so on can be used as placeholders, and you can even nest another in a template string, which I call template inception.
- If both values are not strings, you can convert them to strings as you normally would. For example, if the action is an object, it will be called by its. toString () method to convert it to a string value.
- If you need to write the anti-apostrophe in the template string, you must escape it with a backslash: ' \ ' is equivalent to '.
- Similarly, if you need to introduce the characters $ and {in the template string. No matter what you want to achieve, you need to escape every character with a backslash: ' \$ ' and ' \{'.
Unlike a normal string, a template string can be written in multiple lines:
$ ("#warning"). html ('
All spaces, new lines, and indents in the template string are output as-is in the resulting string.
Well, I told you to make it easy for you to master the template string, from now on the difficulty will increase, you can stop, go to drink a cup of coffee, slowly digest the knowledge before. Really, it's not a shame to go back in time. Lopes Gonçalves once proved to us that the ship would not be crushed by the siren, nor would it fall down from the edge of the Earth, and he eventually crossed the equator, but did he continue to explore the entire southern hemisphere? No, he went home and had a big lunch, and you don't have to repel that feeling.
The future of the anti-apostropheOf course, template strings are not everything:
- They do not automatically escape special characters for you, and in order to avoid cross-site scripting vulnerabilities, you should treat non-confidence data in a special way as you would when stitching a normal string.
- They don't work well with internationalized libraries (which can help you provide different languages for different users), and template strings don't format numbers and dates in a particular language, let alone use different languages at the same time.
- They cannot replace the status of the template engine, for example: mustache, nunjucks.
The template string has no built-in looping syntax, so you cannot iterate through an array to construct a table like HTML, even if it does not support conditional statements. Of course you can do this using template inception, but in my opinion this method is a bit dull.
However, ES6 provides a good derivative tool for JS developers and library designers, and you can use this feature to break through the many limitations of template strings, which we call label templates (tagged templates).
The syntax of the label template is very simple, and an extra tag is appended to the counter-apostrophe at the beginning of the template string. Our first example will add a saferhtml tag, which we will use to address the first limitation above: The automatic escape of special characters.
Please note that the ES6 standard library does not provide similar saferhtml functionality, and we will implement this feature ourselves below.
var message = saferhtml ' <p>${bonk.sender} to show you good. </p> ';
The tag used here is an identifier saferhtml; You can also use a property value as a label, for example: Saferhtml.escape, or a method call, for example: Saferhtml.escape ({ Unicodecontrolcharacters:false}). To be precise, any ES6 member expression (memberexpression) or invocation expression (callexpression) can be used as a label.
As you can see, the non-tagged template string simplifies simple string concatenation, and the label template completely simplifies the function call!
The above code is equivalent to:
var message = saferhtml (TemplateData, Bonk.sender);
TemplateData is an immutable group that stores all the string parts of the template, created by the JS engine for us. Because the placeholder divides the label template into parts of two strings, the array contains two elements, such as Object.freeze ("<p>", "have sent you a bonk.</p>"].
(In fact, there is an attribute in TemplateData, which we will not use in this article, But it is an integral part of the label Template: Templatedata.raw, which is also an array that stores all the string parts of the label template, and if we look at the source code we will find that here is a branch of escape sequence with the form \ n, In TemplateData, however, the new line is true, and the standard label String.raw will use these native strings. )
As a result, the saferhtml function can have thousands of ways to parse strings and placeholders.
Before you continue reading, you may be struggling to think about what to do with saferhtml, and then try to implement it, in the final analysis, it's just a function, you can test your results in Firefox's developer console.
The following is a possible scenario (viewed in gist):
function saferhtml (TemplateData) { var s = templatedata[0]; for (var i = 1; i < arguments.length; i++) { var arg = String (Arguments[i]); Escapes special characters in the placeholder. s + = Arg.replace (/&/g, "&") . Replace (/</g, "<") . Replace (/</g, ">"); Special characters in the template are not escaped. s + = Templatedata[i]; } return s;}
With this definition, the label template saferhtml ' <p>${bonk.sender} is good for you. </p> ' may extend to string ' <p>es6<3er to you. </p> ". Even if a maliciously named user, such as "Hacker Steve<script>alert (' XSS ');</script>", sends a harassing message to another user, the message will be escaped to a normal string anyway, Other users are not threatened by potential attacks.
(By the way, if you feel that the way you use parameter objects inside a function in the above code makes you feel dull, look forward to the next masterpiece, another new feature in ES6 will surely make your eyes shine!) )
Just one simple example is not enough to illustrate the flexibility of the label template, so let's review our previous list of template string limitations and see what else you can do differently.
- The template string does not automatically escape special characters. But as we've seen, with the label template, you can write a label function to solve the problem yourself.
In fact, you can do better than that.
From a security standpoint, the saferhtml function I implemented is quite fragile, and you need to escape the special characters of different parts of the HTML in a number of different ways, saferhtml can not be escaped all. But with a little effort, you can write a more intelligent saferhtml function, which can parse the HTML bits in the string in the TemplateData, analyze which placeholder is pure HTML, which is the intrinsic attribute of the element, need to escape ' and ' Which is the URL of the query string that needs to be URL escaped rather than HTML escaped, and so on. The smart saferhtml function can correctly escape each placeholder.
The parsing speed of HTML is very slow, does this method sound slightly farfetched? Fortunately, the string portion of the label template does not change when the template is re-evaluated. Saferhtml can cache all the parsing results to speed up subsequent calls. (the cache can be stored in the form of another feature--weakmap of ES6, and we'll continue in-depth discussions in future articles.) )
- Template strings have no built-in internationalization features, but with tags, we can add these features. Jack Hsu's blog post shows the specific implementation process. I would like to point out here:
i18n ' Hello ${name}, you are ${amount}:c (CAD) in the your bank account. '//= Hallo Bob, Sie haben 1.234,56 $CA auf Ihrem B Ankkonto.
Notice the details of the run in this example, both name and amount are JavaScript for normal interpolation, but there is a different code: C (CAD), which Jack puts into the string portion of the template. JavaScript is supposed to be handled by the JavaScript engine, and the string part is handled by Jack's i18n tag. Users can learn from I18N's documentation that: C (CAD) represents the currency unit of the Canadian dollar.
This is the most practical application of the label template.
- Template strings cannot be substituted for mustache and nunjucks, partly because there is no built-in loop or conditional statement syntax in the template string. Let's look at how to solve this problem, if JS does not provide this feature, we will write a tag to provide the corresponding support.
Based on the purely fictitious template language//ES6 label template. var libraryhtml = Hashtemplate ' <ul> #for book in ${mybooks} <li><i>#{book.title}</ I> by #{book.author}</li> #end </ul> ';
The flexibility of the label template is much more than that, remember that the parameters of the label function are not automatically converted to strings, they can be any value, like the return value, and the label template may not even be a string! You can use custom tags to create regular expressions, dom trees, pictures, the entire asynchronous process represented by promises, JS data structures, GL shaders ...
Tag Templates Welcome Library designers to create powerful domain-specific languages with an open attitude. These languages may not look like JS, but they can still be seamlessly embedded in JS and interact intelligently with other language features of JS. I do not know where this feature will lead us, but it is an infinite possibility, which makes me very excited!
When can I start using this feature?
On the server side, Io.js supports ES6 template strings.
On the browser side, Firefox 34+ supports template strings. They were implemented by Guptha Rajagopal of the Intern project team last summer. Template strings are also supported in Chrome 41+, but neither IE nor Safari is supported. So far, if you want to use the function of template strings on the Web side, you will need Babel or traceur to assist you in ES6 to ES5 code translation, and you can use this feature immediately in typescript.
Wait--so markdown?
Well? Oh... That's a good question.
(This chapter has nothing to do with JavaScript, so if you don't use markdown, you can skip this chapter.) )
For template strings, both markdown and JavaScript now use ' characters to represent something special. In fact, in Markdown, the anti-apostrophe is used to split the code fragment in the middle of the inline text.
This will bring many problems! If you write such a document in Markdown:
To display a message, write ' alert (' Hello world! ') '.
It will appear like this:
To display a message, write alert (Hello world!).
Notice that the inverse apostrophe in the output text disappears. Markdown interprets all four anti-apostrophes as code separators and replaces them with HTML tags.
To avoid this, let's take advantage of a little-known feature in Markdown, where you can use multiline backslashes as code separators, like this:
To display a message, write ' alert (' Hello world! ') '.
There are specific code details in this gist, which is written by markdown, so you can view the source code directly.
ES6 (iv): template string