三、模版字符串

JavaScript’s strings have been fairly limited when compared to those in other languages. Template strings add new syntax to allow the creation of domain-specific languages (DSLs) for working with content in a way that is safer than the solutions we have today. The description on the template string strawman was as follows

  与其他的语言相比,js的字符串受到了很大的限制。模版字符串是新增加的语法允许创建开发领域特定语言(DSLs)来处理内容,使用这种方式比我们现在使用的解决办法更加安全。关于模版字符串的解释如下:


This scheme extends ECMAScript syntax with syntactic sugar to allow libraries to provide DSLs that easily produce, query, and manipulate content from other languages that are immune or resistant to injection attacks such as XSS, SQL Injection, etc.

  这个计划通过“语法糖”的形式扩展了ECMAScript的语法,允许各种库提供DSLs语法,使得在其他语言内创建、查询和操作内容更加容易,可以免除和抵抗注入攻击例如XSS和SQL注入等。


In reality, though, template strings are ECMAScript 6’s answer to several ongoing problems in JavaScript:

  实际上,模版字符串是ES6用来解决js中现存的几个问题的方法:

  • Multiline strings - JavaScript has never had a formal concept of multiline strings.
  • 多行字符串-js一直没有多行字符串的正式的概念。
  • Basic string formatting - The ability to substitute parts of the string for values contained in variables.
  • 基本的字符串格式化-能够替换变量中所包含的部分字符串的值
  • HTML escaping - The ability to transform a string such that it is safe to insert into HTML.
  • HTML转义-能够转化字符串这样插入到html中更加安全。

Rather than trying to add more functionality to JavaScript’s already-existing strings, template strings represent an entirely new approach to solving these problems.

  不是在js已经存在的字符串上增加大量的功能,模版字符串展现出一种全新的解决这些问题的方法。

基本语法

At their simplest, template strings act like regular strings that are delimited by backticks (`) instead of double or single quotes. For example:

  最简单的,模版字符串和普通字符串一样,只不过界定符号是“`”而不是双引号或者单引号。例如:

let message = `Hello world!`;console.log(message);               // "Hello world!"
console.log(typeof message);        // "string"
console.log(message.length);        // 12

This code demonstrates that the variable message contains a normal JavaScript string. The template string syntax only is used to create the string value, which is then assigned to message.

  这段代码展示了变量message包含一个普通的js字符串。模版字符串的语法只是用来创建字符串值,接着赋值给message。

If you want to use a backtick in your string, then you need only escape it by using a backslash (\):

  如果你想在字符串中使用`,你需要通过凡斜杠(\)转义一下:

let message = `\`Hello\` world!`;console.log(message);               // "`Hello` world!"
console.log(typeof message);        // "string"
console.log(message.length);        // 14

There’s no need to escape either double or single quotes inside of template strings.

在模版字符串内部,不需要转义单、双引号。

多行字符串

Ever since the first version of JavaScript, developers have longed for a way to create multiline strings in JavaScript. When using double or single quotes, strings must be completely contained on a single line. JavaScript has long had a syntax bug that would allow multiline strings by using a backslash (\) before a newline, such as:

  自从第一代js版本开始,开发者就渴望能够有一种方法在js中创建多行字符串。当使用单、双引号的时候,字符串必须包含在一行内。js长期以来都有一个语法错误-允许多行字符串在新的一行开始使用反斜杠(\),例如:

let message = "Multiline \
string";

Despite this working in all major JavaScripte engines, the behavior was defined as a bug and many recommended avoiding its usage.

尽管这种方式可以在所有的主要js引擎下工作,但是这种行为定义了一个bug,许多建议避免使用这种方式。

Other attempts to create multiline strings usually relied on arrays or string concatenation, such as:

  其他的试图创建多行字符串通常依赖于数组和字符串连接,例如:

let message = ["Multiline ","string"
].join("");let message = "Multiline " +"string";

All of the ways developers worked around JavaScript’s lack of multiline strings left something to be desired.

开发者所使用的这些方式都是因为js缺少多行字符串。

Template strings make multiline strings easy because there is no special syntax. Just include a newline where you want and it shows up in the result. For example:

模版字符串使得多行字符串变得简单因为没有什么特殊的语法。只是增加一个新行当你需要和希望在结果中显示的时候。例如:

let message = `Multiline
string`;console.log(message);           // "Multiline//  string"
console.log(message.length);    // 16

All whitespace inside of the backticks is considered to be part of the string, so be careful with indentation. For example:

  在``之内的所有空格都被认为是字符串的一部分,所以排版的时候要小心。例如:

let message = `Multilinestring`;console.log(message);           // "Multiline//                 string"
console.log(message.length);    // 31

In this code, all of the whitespace before the second line of the template string is considered to be a part of the string itself. If making the text line up with proper indentation is important to you, then you consider leaving nothing on the first line of a multiline template string and then indenting after that, such as this:

  在这段代码中,模版字符串第二行之前的所有空格都被认为是字符串本身的一部分。如果正确的文本排列很重要,那么模版字符串第一行之前不要有任何内容然后在排版,例如:

let html = `
<div><h1>Title</h1>
</div>`.trim();

This code begins the template string on the first line but doesn’t have any text until the second. The HTML tags are indented to look correct and then the trim() method is called to remove the initial (empty) line.

  这段代码中,模版字符串从第一行开始但是直到第二行才有文本内容。HTML标签的排版看着是正确的接着使用trim方法删除第一行。

If you prefer, you can also use \n in a template string to indicate where a newline should be inserted:

如果你喜欢,你可以在模版字符串中使用\n来表示增加新行。

let message = `Multiline\nstring`;console.log(message);           // "Multiline//  string"
console.log(message.length);    // 16

置换

To this point, template strings may look like a fancier way of defining normal JavaScript strings. The real difference is with template string substitutions. Substitutions allow you to embed any valid JavaScript expression inside of a template string and have the result be output as part of the string.

  对于这一点,模版字符串看起来更像是定义普通js字符串的一个空想的方式。主要的区别就是模版字符串替换。替换允许你在模版字符串中插入任何有效的js表达式,表达式的结果是字符串的一部分。

Substitutions are delimited by an opening ${ and a closing }, within which you can use any JavaScript expression. At its simplest, substitutions let you embed local variables directly into the result string, like this:

替换的界定符号的开始符号是${,结束符号是},在这之间你可以使用任何的js表达式。最简单的,替换允许你插入本地的变量直接输出结果字符串,像这样:
let name = "Nicholas",message = `Hello, ${name}.`;console.log(message);       // "Hello, Nicholas."

The substitution ${name} accessed the local variable name to insert it into the string. The message variable then holds the result of the substitution immediately.

替换字符串${name}取得来本地变量name的值然后插入到了字符串中。message变量的值立即替换了置换表达式。


Template strings can access any variable that is accessible in the scope in which it is defined. Attempting to use an undeclared variable in a template string results in an error being thrown in both strict and non-strict modes.

模版字符串可以获取在当前作用域中可获取的任意变量。在模版字符串中试图使用未定义的变量或导致错误,无论是在strict模式还是non-strict模式下。


Since all substitutions are JavaScript expressions, it’s possible to substitute more than just simple variable names. You can easily embed calculations, function calls, and more. For example:

  既然所有的置换表达式都是js表达式,那么就能够不仅仅是替换变量。你可以嵌入运算和函数调用等等。

let count = 10,price = 0.25,message = `${count} items cost $${(count * price).toFixed(2)}.`;console.log(message);       // "10 items cost $2.50."

This code performs a calculation as part of the template string. The variables count and price are multiplied together to get a result, and then formatted to two decimal places using .toFixed(). The dollar sign before the second substitution is output as-is because it’s not followed by an opening curly brace.

这段代码执行一个运算作为模版字符串的一部分。变量counts和price相乘得出结果,接着使用.toFixed()函数保留两位小数点后两位有效数字。第二个置换表达式之前的$原样输出,因为$之后没有{。

标签模版

To this point, you’ve seen how template strings can be used for multiline strings and to insert values into strings without using concatenation. The real power of template strings comes from tagged templates. A template tag performs a transformation on the template string and returns the final string value. This tag is specified at the start of the template, just before the first ` character, such as:

  关于这一点,你已经知道模版字符串可以用于多行字符串和不必使用串联就能向字符串中插入值。模版字符串最有影响力的是标签模版。一个模版标签是在模版字符串上执行一个转化和返回最终的字符串值。这个标签在模版的最初指定,就在第一个`符号之前,例如:

let message = tag`Hello world`;

In this example, tag is the template tag to apply to `Hello world`.

在这个例子中,tag是一个模版标签适用于`Hello world`。

定义标签

A tag is simply a function that is called with the processed template string data. The function receives data about the template string as individual pieces that the tag must then combined to create the finished value. The first argument is an array containing the literal strings as they are interpreted by JavaScript. Each subsequent argument is the interpreted value of each substitution. Tag functions are typically defined using rest arguments to make dealing with the data easier:

  一个标签只是一个简单的函数调用,加工模版字符串数据。这个函数接受一个模版字符串的数据作为独立部分,然后和标签结合到一起创建出最终值。第一个参数是一个包含字符串字面量的数组,可以被js解释。每一个随后的参数都是每一个置换表达式解释的值。标签函数通常使用rest参数来更加简单的处理数据。

function tag(literals, ...substitutions) {// return a string
}

To better understand what is passed to tags, consider the following:

为了更好的理解是什么传给了tag,思考以下的代码:

let count = 10,price = 0.25,message = passthru`${count} items cost $${(count * price).toFixed(2)}.`;

If you had a function called passthru(), that function would receive three arguments:

  如果你有一个函数叫做passthru,这个函数将会接受以下的参数:

  1. literals, containing:
  2. 字符串字面量包含:
    • "" - the empty string before the first substitution
    • ""-第一个置换表达式之前的空字符串
    • " items cost $" - the string after the first substitution and before the second
    • " items cost $"-第一个置换表达式之后和第二个置换表达式之前的内容。
    • "." - the string after the second substitution
    • "."-第二个置换表达式之后的内容。
  3. 10 - the interpreted value for count (this becomes substitutions[0])
  4. 10 - count解释得到的值(这个是substitutions[0])
  5. "2.50" - the interpreted value for (count * price).toFixed(2) (this becomes substitutions[2])
  6. "2.50"-(count*price).toFixed(2)的值(这个是substitutions[2])

Note that the first item in literals is an empty string. This is to ensure that literals[0] is always the start of the string, just like literals[literals.length - 1] is always the end of the string. There is always one fewer substitution than literal, which is to say that substitutions.length === literals.length - 1 all the time.

  注意,literals的第一项的值是空字符串,这是为了确保literals[0]总是以字符串开头,就像是literals[literals.length - 1]总是字符串的结尾。置换表达式总是比literal少一个,也就是说在任何时候substitutions.length === literals.length - 1。

Using this pattern, the literals and substitutions arrays can be interweaved to create the result. The first item in literals comes first, then the first item in substitutions, and so on, until the string has been completed. So to mimic the default behavior of template, you need only define a function that performs this operation:

使用这种方式,literals和substitutions数组可以相互混合创建一个结果。首先是literals的第一项,接着是substitutions的第一项等等,知道字符串完成。所以为了模仿模版的默认行为,你需要定义一个函数来执行这个操作:

function passthru(literals, ...substitutions) {let result = "";// run the loop only for the substitution countfor (let i = 0; i < substitutions.length; i++) {result += literals[i];result += substitutions[i];}// add the last literalresult += literals[literals.length - 1];return result;
}let count = 10,price = 0.25,message = passthru`${count} items cost $${(count * price).toFixed(2)}.`;console.log(message);       // "10 items cost $2.50."

This example defines a passthru tag that performs the same transformation as the default template string behavior. The only trick is to use substitutions.length for the loop rather than literals.length to avoid accidentally going past the end of substitutions. This works because the relationship between literals and substitutions is well-defined.

  这个例子定义了一个pasthru的标签, 这个标签和默认的模版字符串执行相同的转换行为。使用substitutions.length来循环而不是literals.length来避免意外的循环到substitutions的最末端。因为literals和substitutions定义明确,所以能够很好的工作。


The values contained in substitutions are not necessarily strings. If an expression is evaluated to be a number, as in the previous example, then the numeric value is passed in. It’s part of the tag’s job to determine how such values should be output in the result.

  substitutions中包含的值不一定都必须是字符串形式。如果一个表达式的求值结果是一个数字,像之前的例子,那么数字的值就会传进去。什么样的值输出什么样的结果是标签工作的一部分。


Using Raw Values - 使用原始值

Template tags also have access to raw string information, which primarily means access to character escapes before they are transformed into their character equivalents. The simplest way to work with raw string values is to the built-in String.raw() tag. For example:

  模版标签也可以获取原始字符串信息,原始的意思是可以获取转换成字符相等的转义字符之前的值。最简单的原始字符串的工作方式就是嵌入String.raw()标签。例如:

let message1 = `Multiline\nstring`,message2 = String.raw`Multiline\nstring`;console.log(message1);          // "Multiline//  string"
console.log(message2);          // "Multiline\\nstring"

In this code, the \n in message1 is interpreted as a newline while the \n in message2 is returned in its raw form of "\\n" (two characters, the slash and n). Retrieving the raw string information in this way allows for more complex processing (when necessary).

  在这段代码中,message1中的\n被转义为一个新行,message2中的\n返回她原始的形式“\\n”(两个字符,\和n)。通过这种方式检索原始字符串的信息允许更多复杂的操作(当需要的情况下)。

The raw string information is also passed into template tags. The first argument in a tag function is an array with an extra property called raw. The raw property is an array containing the raw equivalent of each literal value. So the value in literals[0] always has an equivalent literals.raw[0] that contains the raw string information. Knowing that, it’s possible to mimic String.raw() using the following:

  原始的字符串信息也会传入模版标签中。标签函数中的第一个参数是一个数组,这个数组有一个额外的属性叫做raw。raw属性是一个数组,这个数组包含了每一个值的对应的原始值。所以literals[0]永远都有一个对应的literals.raw[0]包含了原始字符串信息,可以通过以下的例子模范String.raw():

function raw(literals, ...substitutions) {let result = "";// run the loop only for the substitution countfor (let i = 0; i < substitutions.length; i++) {result += literals.raw[i];      // use raw values insteadresult += substitutions[i];}// add the last literalresult += literals.raw[literals.length - 1];return result;
}let message = raw`Multiline\nstring`;console.log(message);           // "Multiline\\nstring"
console.log(message.length);    // 17

This example uses literals.raw instead of literals to output the string result. That means any character escapes, including Unicode code point escapes, will be returned in their raw form.

  这个例子中使用了literals.raw替换了literals输出字符串结果。意味着任何的自负转换,包括Unicode码点转义,也会返回原始的形式。

转载于:https://www.cnblogs.com/avivaWang/p/4341095.html

ECMAScript6 模版字符串相关推荐

  1. 20181210-es6(letconst解构模版字符串原理 展开运算符、剩余运算符运用 深拷贝原理 reduce原理 箭头函数)...

    变量声明 var 特点: 1.可以重复声明 2.不能定义常量 3.不支持块级作用域 复制代码 let //1.不存在预解释 变量提升 //2.暂时性死区 //3.具备块级,同一块内不能重复声明;let ...

  2. 03-1.JavaScript基础语法略写/模版字符串

    基础语法 参考前端基础之JavaScript - Q1mi - 博客园 略写原因 由于后续主要用jQuery编写,jQuery简化编程.大概了解JavaScript语法即可. jQuery是一个轻量级 ...

  3. JS基础学习(十):字符串的大小写转换、trim()方法、JS字符串截取和模版字符串

    1.字符串的大小写转换 字符串将小写字母转化为大写字母使用:toUpperCase 字符串将大写字母转化为小写字母使用:toLowerCase ASEDECFSXV        转化小写       ...

  4. ie模版字符串_【探秘ES6】系列专栏:模版字符串

    [探秘ES6]系列专栏(四):模版字符串 为什么80%的码农都做不了架构师?>>> ... [探秘ES6]系列专栏 [探秘ES6]系列专栏(一):ES6简介 [探秘ES6]系列专栏( ...

  5. vue语法 `${ }` (模版字符串)

    const name = '小缘' const age = 14 console.info(`大家好,我叫${name},今年${age}岁了`) // 等价于 console.info('大家好,我 ...

  6. ie模版字符串_字符串模板、模板字符串、Vue中使用template等等。

    1:模板字符遇新是直朋能到串 传统的一如分算需上来处一定迹面数一跳这件我子作JS语言,输出模板新直能分支调二浏页器朋代说,事刚需求是这样写的: $('#result').append( 'There ...

  7. ie模版字符串_字符串(String)模板引擎被视为是有害的

    用模板和一些数据来生成HTML不是一项特别繁重的任务.那些你必须要为HTML做的事才是效率低下的部分. 假如你有一个代表改变数据的UI: Current score: {{currentScore}} ...

  8. vue学习之二ECMAScript6标准

    一.ECMAScript6标准简述 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScr ...

  9. 「译」在JavaScript中将值转换为字符串的5种方法

    原文: 5 Ways to Convert a Value to String in JavaScript 如果您关注Airbnb的样式指南,首选方法是使用"String()"? ...

最新文章

  1. R6010-abort() has been called,Error openning file ../../modules/highgui/src/cap_ffmpeg_impl.hpp解决方法
  2. 腾讯/字节/华为/旷视 2022届实习面经—计算机视觉方向
  3. 数据蒋堂 | 从一道招聘考题谈起
  4. 美国AI博士指出:60天掌握Python全栈需要...
  5. 使用maven编译YCSB0.1.4对cassandra进行性能测试
  6. windows和linux加密u盘,linux挂载windows的各种格式U盘
  7. 计算机文件自动备份到移动硬盘,如何让电脑文件自动备份到指定的邮箱里?或者备份到指定的磁盘里...
  8. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数 列表表达式/列表重写...
  9. 【数字信号】基于matlab GUI DTMF双音多频电话拨号仿真【含Matlab源码 805期】
  10. IE和ff下javascript解释的区别
  11. 第四章 Python数据预处理之划分训练集与测试集
  12. 摄影师伴侣——ON1系列摄影后期图像处理软件合集
  13. 备用计算机机房管理制度,计算机机房管理制度
  14. 自己搭的12V 电机驱动电路设计
  15. 苹果app退款_苹果App Store应用,5月最新退款
  16. 微信小程序 手机号 邮箱正则表达式验证
  17. 手机\固定电话座机呼叫转移设置方法
  18. 系统迁移后无法正常开机相关心得
  19. 单片机 STM32 HAL PCF8574 例子代码
  20. NBA球星管理系统 v1.0

热门文章

  1. 面试中几个基本的重要问题总结
  2. 哈尔滨有线电视频道表
  3. can总线报文是固定的吗_CAN总线传输协议
  4. php session传数组,php把数组存到session的方法
  5. html单击出现下拉菜单,*OnClick实现点击主菜单时出现下拉菜单,已实现但是有问题,求助!*...
  6. 随输入动态改变ui_深入详解 Jetpack Compose | 优化 UI 构建
  7. 设计模式:000设计模式与面向对象介绍
  8. aspose 转pdf表格大小乱了_自己写了一个小工具类:pdf转word,没有页数和大小限制,保真!...
  9. java 本年第一天_JAVA获取本周 本月 本年 第一天和最后一天
  10. Java 算法 学做菜