JS 的字符串相对其他语言来说功能总是有限的,事实上,ES5中一直缺乏许多特性,如多行字符串、字符串格式化、HTML转义等。ES6通过模板字面量的方式进行了填补,模板字面量试着跳出JS已有的字符串体系,通过一些全新的方法来解决类似的问题。

一、基本用法

  模板字面量是增强版的字符串,它用反引号(`)标识

二、多行字符串

  自javascript诞生起,开发者们就一直在寻找一种能创建多行字符串的方法。如果使用双引号或单引号,字符串一定要在同一行才行

1、反斜杠

  由于javascript长期以来一直存在一个语法bug,在换行之前的反斜线( \ )可以承接下一行的代码,于是可以利用这个bug来创建多行字符串,但是字符串打印输出时不会有换行,因为反斜线被视为延续符号而不是新行的符号。为了在输出中显示换行,需要手动加入换行符

var message = "Multiline \n\
string";
// "Multiline
// string"
console.log(message);

  在所有主流的 JS 引擎中,此代码都会输出两行,但是该行为被认定为一个 bug ,并且许多开发者都建议应避免这么做。在ES6之前,通常都依靠数组或字符串的拼接来创建多行字符串。

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

  JS一直以来都不支持多行字符串,开发者的种种解决方法都不够完美。

2、反引号

  ES6 的模板字面量使多行字符串更易创建,因为它不需要特殊的语法,只需在想要的位置直接换行即可,此处的换行会同步出现在结果中。

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

  在反引号之内的所有空白符都是字符串的一部分,因此需要特别留意缩进。

  模板字面量里的所有空白符都被视为字符串自身的一部分

  当然,也可以在模板字面量中使用 \n 来指示换行的插入位置

let aaa=`aab\ndd`;
console.log(aaa,aaa.length)
//aab
//dd
//

三、变量占位符

  模板字面量看上去仅仅是普通JS字符串的升级版,但二者之间真正的区别在于模板字面量的变量占位符。变量占位符允许将任何有效的JS表达式嵌入到模板字面量中,并将其结果输出为字符串的一部分。

  变量占位符由起始的 ${ 与结束的 } 来界定,之间允许放入任意的 JS 表达式。最简单的变量占位符允许将本地变量直接嵌入到结果字符串中。

let name = "Nicholas",
message = `Hello, ${name}.`;
console.log(message); // "Hello, Nicholas."

  占位符 ${name} 会访问本地变量 name ,并将其值插入到 message 字符串中。 message变量会立即保留该占位符的结果

  既然占位符是JS表达式,那么可替换的就不仅仅是简单的变量名。可以轻易嵌入运算符、函数调用等

let count = ,
price = 0.25,
message = `${count} items cost $${(count * price).toFixed()}.`;
console.log(message); // "10 items cost $2.50."
function fn() {
return "Hello World";
} `foo ${fn()} bar`
// foo Hello World bar

  模板字面量本身也是 JS 表达式,因此可以将模板字面量嵌入到另一个模板字面量内部

let name = "Nicholas",
message = `Hello, ${
`my name is ${ name }`
}.`;
console.log(message); // "Hello, my name is Nicholas."

四、标签模板

  模板字面量真正的威力来自于标签模板,每个模板标签都可以执行模板字面量上的转换并返回最终的字符串值。标签指的是在模板字面量第一个反引号'`'前方标注的字符串

let message = tag`Hello world`;
//在这个示例中, tag 就是应用到 `Hello world` 模板字面量上的模板标签

1、定义标签

  标签可以是一个函数,调用时传入加工过的模板字面量各部分数据,但必须结合每个部分来创建结果。第一个参数是一个数组,包含Javascript解释过后的字面量字符串,它之后的所有参数都是每一个占位符的解释值

  标签函数通常使用不定参数特性来定义占位符,从而简化数据处理的过程

function tag(literals, ...substitutions) {
// 返回一个字符串
}

  为了进一步理解传递给tag函数的参数,查看以下代码

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

  如果有一个名为passthru()的函数,那么作为一个模板字面量标签,它会接受3个参数:

首先是一个literals数组,包含以下元素:

  1、第一个占位符前的空字符串("")

  2、第一、二个占位符之间的字符串(" items cost $")

  3、第二个占位符后的字符串(".")

下一个参数是变量count的解释值,传参为10,它也成为了substitutions数组里的第一个元素

最后一个参数是(count*price).toFixed(2)的解释值,传参为2.50,它是substitutions数组里的第二个元素

  注意:literals里的第一个元素是一个空字符串,这确保了literals[0]总是字符串的始端,就像literals[literals.length-1]总是字符串的结尾一样。substitutions的数量总比literals少一个,这也意味着表达式substitutions.Iength === literals.Iength-1的结果总为true

var a = ;
var b = ; tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], , );

  通过这种模式,我们可以将literals和substitutions两个数组交织在一起重组结果字符串。先取出literals中的首个元素,再取出substitution中的首个元素,然后交替继续取出每一个元素,直到字符串拼接完成。于是可以通过从两个数组中交替取值的方式模拟模板字面量的默认行为。

function passthru(literals, ...substitutions) {
let result = "";
// 仅使用 substitution 的元素数量来进行循环
for (let i = ; i < substitutions.length; i++) {
result += literals[i];
result += substitutions[i];
}
// 添加最后一个字面量
result += literals[literals.length - ];
return result;
}
let count = ,
price = 0.25,
message = passthru`${count} items cost $${(count * price).toFixed()}.`;
console.log(message); // "10 items cost $2.50."

  这个示例定义了一个passthru标签,模拟模板字面量的默认行为,展示了一次转换过程。此处的小窍门是使用substitutions.length来为循环计数。

2、应用:

  “标签模板”的一个重要应用,就是过滤HTML字符串,防止用户输入恶意内容

var message =
SaferHTML`<p>${sender} has sent you a message.</p>`; function SaferHTML(templateData) {
var s = templateData[];
for (var i = ; i < arguments.length; i++) {
var arg = String(arguments[i]); // Escape special characters in the substitution.
s += arg.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;"); // Don't escape special characters in the template.
s += templateData[i];
}
return s;
}

  上面代码中,sender变量往往是用户提供的,经过SaferHTML函数处理,里面的特殊字符都会被转义

var sender = '<script>alert("abc")</script>'; // 恶意代码
var message = SaferHTML`<p>${sender} has sent you a message.</p>`; console.log(message);// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has sent you a message.</p>

  标签模板的另一个应用,就是多语言转换(国际化处理)

i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"

  模板字符串本身并不能取代模板引擎,因为没有条件判断和循环处理功能,但是通过标签函数,可以自己添加这些功能

// 下面的hashTemplate函数
// 是一个自定义的模板处理函数
var libraryHtml = hashTemplate`
<ul>
#for book in ${myBooks}
<li><i>#{book.title}</i> by #{book.author}</li>
#end
</ul>
`;

五、raw():

  String.raw方法,往往用来充当模板字面量的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字面量

let message1 = `Multiline\nstring`,
message2 = String.raw`Multiline\nstring`;
console.log(message1); // "Multiline
// string"
console.log(message2); // "Multiline\\nstring"
String.raw`Hi\n${+}!`;
// "Hi\\n5!" String.raw`Hi\u000A!`;
// 'Hi\\u000A!' //如果原字符串的斜杠已经转义,那么String.raw不会做任何处理
String.raw`Hi\\n` // "Hi\\n"

  String.raw方法可以作为处理模板字面量的基本方法,它会将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用。

  String.raw方法也可以作为正常的函数使用。这时,它的第一个参数,应该是一个具有raw属性的对象,且raw属性的值应该是一个数组

String.raw({ raw: 'test' }, 0, 1, 2);// 't0e1s2t'

// 等同于
String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2);

ES6里关于模板字面量的拓展的更多相关文章

  1. ES6躬行记(4)——模板字面量

    模板字面量(Template Literal)是一种能够嵌入表达式的格式化字符串,有别于普通字符串,它使用反引号(`)包裹字符序列,而不是双引号或单引号.模板字面量包含特定形式的占位符(${expre ...

  2. ES6模板字面量

    前面的话 JS 的字符串相对其他语言来说功能总是有限的,事实上,ES5中一直缺乏许多特性,如多行字符串.字符串格式化.HTML转义等.ES6通过模板字面量的方式进行了填补,模板字面量试着跳出自己JS已 ...

  3. ES6 模板字面量

    模板字面量 解决的问题 1.多行字符串 一个正式的多行字符串的概念 2.基本的字符串格式化 将变量的值嵌入字符串的能力 3.HTML转义 向HTML插入安全转换后的字符串的能力 (1)基础语法 相当于 ...

  4. ES6入门四:对象字面量扩展与字符串模板字面量

    简洁属性与简洁方法 计算属性名与[[prototype]] super对象(暂时保留解析) 模板字面量(模板字符串) 一.简洁属性与简洁方法 ES6中为了不断优化代码,减低代码的耦合度在语法上下了很大 ...

  5. 学习熟悉箭头函数, 类, 模板字面量, let和const声明

    箭头函数:https://blog.csdn.net/qq_30100043/article/details/53396517 类:https://blog.csdn.net/pcaxb/articl ...

  6. ES6 二进制和八进制字面量

    ES6 支持二进制和八进制的字面量,通过在数字前面添加 0o 或者 0O 即可将其转换为二进制值: let oValue = 0o10; console.log(oValue); // 8 let b ...

  7. 在JavaScript里的“对象字面量”是什么意思?

    字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量.字面量分为字符串字面量(string literal ).数组字面量(array literal)和对象字面量(ob ...

  8. JS:关于JS字面量及其容易忽略的12个小问题

    简要 问题1:不能使用typeof判断一个null对象的数据类型 问题2:用双等号判断两个一样的变量,可能返回false 问题3:对于非十进制,如果超出了数值范围,则会报错 问题4:JS浮点数并不精确 ...

  9. es6对象字面量增强

    相对于ES5,ES6的对象字面量得到了很大程度的增强.这些改进我们可以输入更少的代码同时语法更易于理解.那就一起来看看对象增强的功能.对象字面量简写(Object Literal Shorthand) ...

随机推荐

  1. ZCC loves cube(cube)

    题目描述 调戏完了狗,ZCC开始玩起了积木.ZCC的面前有一块n*n的棋盘,他要用这些1*1*1的积木在棋盘上搭出一个宏伟的建筑.积木有三种颜色,ZCC认为一个建筑要被称为宏伟的应该满足能从正面看到的 ...

  2. php curl模块开启失败解决参考

    现在公司的测试项目和正式项目是部署在同一台服务器上的,为了在重启apache时互不影响,我在服务器上部署了两个apache服务,使用nginx做url转发. 结果正式环境的项目使用curl没有问题,但 ...

  3. Codeforces 934.D A Determined Cleanup

    D. A Determined Cleanup time limit per test 1 second memory limit per test 256 megabytes input stand ...

  4. VSM and VEM Modules

    Information About Modules Cisco Nexus 1000V manages a data center defined by a VirtualCenter. Each s ...

  5. javascript jquery document.ready window.onload

    网易 博客 下载LOFTER客户端 注册登录  加关注 凡图的编程之路 2012年7月从一个编程新手的点点滴滴 首页 日志 LOFTER 相册 博友 关于我     日志       关于我 Holy ...

  6. c/c++: c++函数返回类型什么情况带const

    c++ 函数的返回类型,包括const 什么时候起作用呢? 函数返回值不想其立即修改的. 例子如下,这是一个简单的避免产生隐形返回变量的方法,abc 的函数返回是引用,main函数中第10行,++ 操 ...

  7. Unicode与UTF-8互转(C语言实现) 基本原理

    1. 基础 1.1 ASCII码 我们知道, 在计算机内部, 所有的信息最终都表示为一个二进制的字符串. 每一个二进制位(bit)有0和1两种状态, 因此八个二进制位就可以组合出 256种状态, 这被 ...

  8. 12.OpenStack镜像和存储服务配置

    配置镜像服务 编辑 /etc/glance/glance-api.conf与/etc/glance/glance-registry.conf添加以下内容 [DEFAULT] notification_ ...

  9. 3.安装OpenStack-keystone

    安装keystone(控制器上安装) 使用root用户访问数据库 mysql -uroot -ptoyo123 CREATE DATABASE keystone; GRANT ALL PRIVILEG ...

  10. 如何配置openjdk的 java home

    https://blog.csdn.net/redmoon729/article/details/51671354