说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

【探秘ES6】系列专栏:模版字符串

HTML文档下载 WORD文档下载 PDF文档下载
新一代JavaScript标准,ES6即将发布。【探秘ES6】系列专栏将一一剖析ES6的诸多新特性,让Web开发者对此有清晰全面的了解。本文为系列的第四篇,带你了解ES6的模版字符串(Template Strings)。

ES6作为新一代JavaScript标准,即将与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系列进行翻译,供大家学习借鉴。本文为该系列的第四篇。

前两次学习了生成器和迭代器以后,脑袋有没有一团浆糊?哈哈。我承诺过本次我们将学习一些简单的东西。

那我们现在就开始吧!

“小句号”的基本使用

ES6新引入了一种新的字符串语法——模版字符串(Template Strings),它看起来和普通的字符串很像,区别在于它不是由单引号'或者双引号"来闭合,而是使用`(俗称:小句号)。我们来看个最简单的例子,它们其实就是字符串而已:

context.fillText(`Ceci n'est pas une chaîne.`, x, y);

但是既然它被叫做“模版字符串”,那它应该不仅仅是用小句号来闭合的普通字符串吧?模版字符串让JavaScript有了一个简单的字符串插值功能——既写法美观又能很方便地将JavaScript变量替换到字符串中。

很多情景下都可以用到它,但最打动我的是它在毫不起眼的错误消息中的使用:

function authorize(user, action) {  if (!user.hasPrivilege(action)) {    throw new Error(      `User ${user.name} is not authorized to do ${action}.`);  }}

在这个例子中,${user.name}和${action}被称作模版替换位。在生成的字符串中,JavaScript会用使用user.name和action的变量值来替换字符串的模版替换位。最后生成的字符串为:User jorendorff is not authorized to do hockey(你可以自己试试,我可没忽悠你)。

目前为止,它只是个比+(加号连接符)在语法上略微美观一些而已,你可能想了解更多关于它的细节:

  • 模版替换位中的代码可以是任何JavaScript的表达式,比如函数调用、算数运算等等都是允许的(只要你乐意,你甚至可以在模版字符串中嵌套模版字符串,有种模版中的《盗梦空间》的感觉)。
  • 如果插入的值不是字符串,它将被转换为字符串。例如,如果action是个对象,它的.toString()方法将会被调用。
  • 如果你的模版字符串中包含 ` (小句号),需要使用转义字符`\``,效果相当于 "`"。
  • 举一反三,如果你的模版字符串中需要 ${ 这两个字符,我不想去关心你为什么要这么写,但是你可以使用转义其中任意一个字符:`write \${  或者 $\{`。

与普通字符串不同的是,模版字符串可以写成多行:

$("#warning").html(`  <h1>Watch out!</h1>  <p>Unauthorized hockeying can result in penalties  of up to ${maxPenalty} minutes.</p>`);

在模版字符串中,所有空格、换行、缩进都是逐字输出的。

好的,就像我上篇文章所承诺的,我觉得我必须对你大脑的健康负责。所以给一个小小的警告:接下来的内容就比较费脑一点了。你可以现在就放弃阅读,喝杯咖啡享受一下,放松一下大脑。认真地说,不用为放弃下面的内容而感到羞愧噢。 当Lopes Gonçalves穿过了赤道,证明了不会被可怕的海怪吃掉或掉进地球的尽头,然后他还需要去航行整个完整的南半球来增加论证吗?不需要!他返航了,回到家吃了顿美美的午餐。换做是你也会这么做,对不对?

深入讨论“小句号”

我们来讨论一些模版字符串的局限性。

  • 它不会为你自动转义关键字。为了防止脚本注入,你需要认真小心对待那些不受信任的数据,就像你曾经小心地拼接字符串一样。
  • 它并没有明确地说明如何配合国际化库(一个针对用户所处的国家/语言不同来国际化你的代码的库)来使用。模版字符串不会处理特定语言的数字、日期等的格式化。
  • 它并不能代替像Mustache、Nunjucks这样的模板库。

模版字符串没有内置针对循环的语法——通过数组来循环生成一个HTML表格;甚至条件语句也不支持。(当然,你可以使用模版嵌套来实现,但是这样的方法太笨拙,我认为不可取。)

ES6在模版字符串中为JS开发者和库设计人员提供了一种解决方案来帮助他们处理这些局限性问题。这个特性被称做模版标记。

模版标记的语法很简单。我们只需要在“小句号”的前面加一个额外的标记。在我们接下来的第一个例子中,SaferHTML就是它的标记,我们使用这个标记来处理上面列表中的第一个局限性问题:自动转义关键字。

必须清楚SaferHTML并不是ES6标准库中的内容。在下面我们将会自己来实现它。

var message =  SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;

这里使用了一个标识符SaferHTML来作为标记,标记也可以是一个属性——SaferHTML.escape,甚至可以是一个函数调用——SaferHTML.escape({unicodeControlCharacters: false})。(说明一下,任何ES6的MemberExpressio类或CallExpression类都可以作为标记使用)。

可以看出不含标记的模版字符串适用于简单的字符串拼接。标记模版完全适用于其它场景:如函数调用。

上面的代码与这段等效:

var message =  SaferHTML(templateData, bonk.sender);

templateData 是由模版的字符串部分所组成的不可变数组,由JS引擎为我们提供。下面是一个拥有两个元素的数组,因为在标记模板中他们被模版替换所分割,有两个字符串部分。所以templateData 应该是这个样子的: Object.freeze(["<p>", " has sent you a bonk.</p>"]。

(实际上templateData 还有一个属性。我并不打算在这篇文章中用到它,为了完整性我还是提一下: templateData.raw 是另一个囊括了标记模版中所有字符串部分的数组,它的源码就和它的名称(raw)一样原始——还保留着\n这样的转义序列,而不是被转到新的一行等。标准的String.raw使用了最原始的字符串。)

这样就给了SaferHTML函数很大的自由度,可以用很多可选的方法去解析字符串和替换字符。

现在你一定想弄清楚SaferHTML究竟是怎么实现的,或许你想亲手来尝试实现它。它终究只是个函数而已。你可以再Firefox的控制台中测试一下。

下面是其中一种方式(查看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;}

定义了这个方法以后,SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`将会被解析为 "<p>ES6&lt;3er has sent you a bonk.</p>"。那么你的用户传入的值都是安全的,即使有人恶意地将bonk.sender 赋值为 "Hacker Steve <script>alert('xss');</script>",返回的也是不可执行的字符串,无论这段字符串的含义是什么,都不会有安全漏洞。

(顺便说一句,如果你觉得函数使用参数对象的方式让你感觉这样很笨重,我们下次将换用另一种方法。ES6还有另一个我认为你会喜欢的新特性。)

一个例子并不能说明标记模版的灵活性。让我们再来看看我们能为之前列出的那些模版字符串的局限性做些什么改进。

  • 模版字符串不自动转义特殊字符。但是我们已经看到了,使用标记模版我们就能解决这个问题。实际上,我们能做得更好。

从安全性的角度来看,我的SaferHTML函数功能性非常弱。HTML中不同的地方有不同的关键字需要不同的转义方式。SaferHTML把它们全部都转义,但是我们可以再付出一些努力把SaferHTML写的更精明一点,完全按照字节来解析templateData中的字符串,这样我们就知道哪些替换位是在纯HTML中;哪些是在元素属性中,这些 ‘ 和 “ 就需要转义;那些在URL查询字符串中需要使用URL转义而不是HTML转义等等。它可以准确地对每个替代位进行正确的转义。

也许你会有疑问——HTML解析效率低,这方法是不是很牵强?幸运的是标记模版的字符串部分是固定不变的。SaferHTML可以将这部分的解析结果缓存起来,这样就可以提高运行速度了。(这个缓存可以是一个WeakMap,WeakMap是ES6的新特性,我们在以后的文章中将会对它有所讨论。)

  • 模版字符串没有涉及国际化相关的特性。好在有了标记,这个问题就迎刃而解。Jack Hsu发表了一篇博客为我们迈出了这第一步。下面是一个例子:

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

注意,在这个例子中name和amount是JavaScript,但是这里有一个我们不熟悉的语句——:c(CAD),Jack把它放到了模板的字符串部分。JavaScript理所当然由JavaScript引擎来处理,而字符串部分则有Jack的i18n标记来处理。我们可以从i18n的文档中知道:c(CAD)表示加拿大元,那么amount则表示了加拿大元的数额。

这就是标记模板的作用了。

  • 它并不能代替像Mustache 、Nunjucks这样的模板库,大部分原因是因为它没有内置对循环和条件句的支持。那么现在我们一起来看看如何解决这个问题,准备好了吗?

如果JS没有为我们提供某个特性,那我们就自己写一个!

// 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>`;

它的灵活性还不止于此。记住,标记函数的参数不会自动转换为字符串。它的返回值也是这样,它们可以是任何类型,标记模版不一定是字符串!你可以使用自定义标签来创建自定义正则表达式、DOM树、图片、完整的异步流程、JS数据结构、GL着色器等等。

标记模版鼓励库开发人员去创建强大的基于特定领域的语言。这些语言看起来一点也不像JS,但是他们可以无缝地嵌入JS中并且可以智能地与其它语言进行交互。现在,我想不出其它任何有类似特性的语言,我不知道这个特性将来会给我们的开发带来什么改变,但这个改变应该是令人惊喜的。

我什么时候可以开始使用模版字符串?

在服务端,io.js已经开始支持模版字符串了。

浏览器里,FireFox 34+已经支持模版字符串。去年夏天Guptha Rajagopal已经把它作为一个实习项目。Chrome 41+也支持模板字符串,IE和Safari不支持。现在,如果你想在web项目中使用模版字符串你需要用到Babel或Traceur来支持;你也可以在TypeScript中使用。

在Markdown中可以使用吗?

嗯? 

哦……这是一个好问题。

(这一部分与JavaScript无关。如果你不使用Markdown,可以跳过这一段。)

Markdown和JavaScript都使用 ` 来作为模版字符串的特殊字符。实际上,在Markdown中

它是内联文本的定界符。

如果你在Markdown中用下面的方式来写是会有问题的:

To display a message, write `alert(`hello world!`)`.

显示的结果为:

To display a message, write alert(hello world!).

请注意,在输出中是不会有小句号的。Markdown把这个四个小句号都解释为定界符,在输出结果中被HTML标记替换掉了。

为了避免这种情况,我们一开始在Markdown就采用了一种比较少见的特性:使用多重小句号来作为代码定界符,如下:

To display a message, write ``alert(`hello world!`)``.

可以到Gist上去查看更多细节,它是由Markdown写的,你可以查看源码。

下期预告

下篇文章,我们将学习两个新特性,在其它语言中这两个特性已经被程序员们愉快地使用了几十年了:其中一个是为了那些喜欢尽量避免使用参数的开发人员准备的,另一个是给那些喜欢使用很多参数的人准备的。当然,两种特性都为我们提供了,我们可以根据个人对函数的使用习惯来选择。

这些特性可以直接在Firefox中测试,所以下次我们一起来试一下吧,我们的客座来宾Benjamin Peterson将为大家讲解ES6的default parameters和rest parameters。(译者:向渝 责编:陈秋歌)

原文链接:ES6 In Depth: Template strings

本译文遵循Creative Commons Attribution Share-Alike License v3.0 

相关阅读:

【探秘ES6】系列专栏:ES6简介

【探秘ES6】系列专栏:迭代器和for-of循环

【探秘ES6】系列专栏:生成器

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。  

ajaxStart(callback)-JQuery API ajaxStop(callback)-JQuery API ajaxSuccess(callback)-JQuery API load(url, params, callback)-JQuery API loadIfModified(url, params, callback)-JQuery API serialize()-JQuery API Accordion(settings)-JQuery API activate(index)-JQuery API button(hash)-JQuery API center()-JQuery API $.cookie(name)-JQuery API $.cookie(name, value, options)-JQuery API height()-JQuery API innerHeight()-JQuery API innerWidth()-JQuery API offset()-JQuery API outerHeight()-JQuery API outerWidth()-JQuery API scrollLeft()-JQuery API scrollTop()-JQuery API width()-JQuery API ajaxForm(object)-JQuery API ajaxSubmit(object)-JQuery API clearForm()-JQuery API clearInputs()-JQuery API fieldSerialize(true)-JQuery API fieldValue(successful)-JQuery API formSerialize(true)-JQuery API formToArray(true)-JQuery API resetForm()-JQuery API $.recallDroppables()-JQuery API 急!!请问如何通过程序检测一个系统中的Office版本(比如:中文版,英文版) 请问有人知道上海伍尔特国际咨询公司的朋友嘛 ? 怎样在信件里面自动添加信息? 2万元寻人力资源管理软件 友情链接,我的网站http://fullstrong.myetang.com/ 有没有人统计过windows有多少个api加上shell呢? 请问:winsock的SendData的调用,在收发email时改如何设置参数 请问gdk和gtk的函数库是怎么按装的? 搞不定了,7456..来回切换窗口状态的问题, 有源码 友情链接,我的网站http://fullstrong.myetang.com/ 请问RTDB(实时数据库和商用数据库的区别) 各位高手,请问在Tomcat下怎么解决中文问题? XML如何实现曲线图、饼图、梯形图的表示? “红萝卜的胳膊白萝卜的腿”谁听过? 问一个语法的问题? 读入文本的回车和换行为什么都没有了 类似HTML为扩展名的有哪几种文件 安装php+Mysql+Apache时出现的一个小问题,请高手指教! 取url中?后参数的javascript函数是什么? 怎么样来控制声道,如左声道,右声道,立体声? 简单问题,能介绍一下dual吗?? 新操作系统,老编程工具 这样能兼容吗? applet请教 衷心祝愿正在找工作的朋友们心想事成 浪费了几百份了,从来没人回答这个问题,窝气阿,up以下也好啊?????? 米卢是神奇的,中国队更神奇! 有谁知道哪里可以下载PDF Reference Manual中文版? 请教各位大虾! 怎样能把oracle数据库中的所有用户表的结构以及主键外键信息导出为sql 脚本? 踢得真不公平,真是21人踢我们一个人! 友情链接,我的网站http://fullstrong.myetang.com/ VB里面怎么编译出,不用安装的运行程序,请问在那里设置?(上限5分,人人有分)? 哪位大师知道在VC中怎样实现视频捕捉功能 有谁知道mp3的压缩和解压缩算法 问一下关于文件图标的问题。 pb6.5,win2000中文板,Oracle817.在oracle中连接数据库正确。在pb中连接数据库错误。什么内存出错,还有pbo7360.dll acess error之类的错 急!!请问如何将扩展名为PLB的文件转换为SQL文件 关于datagrid的selecteditem事件 谁能告诉我如何给回答对的人加分呀,散分啦 有谁知道哪里可以下载PDF Reference Manual中文版? 文件上传,然后把文件中的数据写入数据库,怎样做到。 问一个很菜的问题 100分在线等待:请介绍resin 如何在listview在作模糊查询。100分 ODBC下正确,BDE下出错?为什么?分数不够可以再加 项目中的角色 vb中怎样终止一个正在运行的应用程序? ADO编程,怎么把SQL Server里的DateTime取到windows的SYSTEMTIME或time_t里? 简单问题!Webbrowser控件 谁用过在那里加?还有程序中怎么打开如“http://www.csdn.net”的页? 小问题,抢分呀 将一个数据库a1的记录追加到另一个数据库a2记录后面的SQL语句怎么写? 380v的电能电死人吗 提升重物的机械效率跟滑轮组机械效率、拉力机械效率什么的有什么区别没有? 五大湖附近地区属于美国农业带的什么带?该农业带的有利条件是什么? 内蒙古阿拉善银星风力发电有限公司 翻译成蒙古语是什么 在提升相同重物时的拉力是否是影响滑轮组机械效率的因素? 有氧呼吸和无氧呼吸的方程式 各种糖的化学式越多越好! 地理信息系统(GIS)应用现状及发展趋势.地理信息系统(GIS)应用现状及发展趋势?各位哥哥姐姐,小弟考研问题(最后一道大题),希望知道的能尽快给我一个答复,尽量详细点, 有没有人对EVP有兴趣的?展开是:Electronic Voice Phenomenon ,简称EVP,超自然电子异象. 糖的化学式 地理信息系统GIS设某项应用为核电站选址,要求核电站临近海湾,交通便捷,地形坡度小于5%,地质条件安全,并避开居民区,请试以GIS方法,设计该位置选择的应用模型(具体说出是哪种模型),用框 超自然电子异象( Electronic Voice Phenomenon )」简称EVP超自然电子异象( Electronic Voice Phenomenon求大神翻译成英文这些研究小组每天透过一种叫做转换联系仪器(Transcommunicat 有规律地拦截电视机和收 GIS的应用领域有哪些? 谁有地理信息系统GIS的软件啊?就是arcgis软件 最好带上安装方法啊~ 甲苯合成COOHOH过程 柠檬酸钠化学式是什么?吃了对人体有害吗? 由于刹车,汽车开始以12米/秒的初速度做匀减速直线运动,若刹车后在第1秒内的平均速度为9.5M/S,那么汽车在车后3秒内的位移是 米 400吨甘蔗,可以炸出蔗糖64吨,这种甘泽的出糖率是( )如果要炸出蔗糖200吨需要()吨新村农场去年中土豆5分之1公顷,平均每公顷手土豆37.4定,今年计划种植面积不变,每公顷产量加一成五.估 gis的应用领域有多宽,有多大的前途? 请问现在乙醇汽油的市场前景...开发难度.成本投资 之类的...最好能详细一些... 世上超自然电子现象怎么解释,灵异到底存在吗? gis的应用有哪些?GIS的发展使? 英语翻译2.1foundationIn order to inspect the electric fittings in the foundation remove ametal plate from the ground platform and go down into the foundation.2.1.1water entryinspect the foundation for traces of water entry in case of stagnant wat 搜集[亲身经历]的超自然灵异事件佳人真心搜集,您要是听说的,自编的或者复制的 就不麻烦您了希望大家慷慨的说一说,一起研究研究!一楼12岁的弟弟,你说的事情我有点晕哦,蓝色的东西还能 偏航器用英语怎么说 风力发电的发展状况及相关问题 (翻译成英文怎么翻译 求高手帮忙 急 谢谢) 家庭照明用led节能灯多少瓦合适?LED节能灯的瓦数和传统的节能灯、白炽灯的瓦数相同吗?如果不同, 求将表格中的化学式转换成下面的样子. 金属键强弱和金属导电性的关系 我想在本地办一个LED节能灯组装厂,家用灯饰开一个小厂子,3-5个人吧,组装LED节能灯,一个能组装多少个节能灯? 几个高一化学式的转换比较基础的在线等很急!金属--成碱性氧化物(互换)碱性氧化物--碱 (有3个)碱--盐 1个盐--盐酸--盐酸性氧化物--酸 (互换)非金属--酸性氧化物 1个能写出几个方程式 金属导电性判断铜,银,铝,铁,金导电性强弱怎么判断啊需要详细的答案啊 谢谢 物体向上速度变快,向上变慢,为什么?对不起,是说错了 应该是问:物体向下速度变快,向上变慢,为什么? gis在煤矿上的应用有哪些 什么碱不溶于酸,不溶于水 九年级物理力的方向 初三酸碱盐,转换, 噪音污染的有关知识 谁能给我总结总结 互联网对农村的利于弊?没人 能回答 机械噪音 人体 危害我是开数控通快2020机床的,机床噪音每天很大,请问它对人体的损害有哪些?同时要防止补充什么营养》谢谢! GIS的应用范围有多广?谁给点具体的例子 请问飞机场存在哪些污染?如噪声污染,电磁污染,空气污染等,有哪些危害性?最好详细些. 光合作用与有氧呼吸的区别与联系 GIS的应用GIS可以用来( )A.获取灾区数字信息 B.在救灾中导航 C.对灾害发生地定位 D.建立救灾决策指挥系统 提倡使用下列产品,其中与环境保护无关的是() A.加碘食盐 B.无铅汽油 36题,关于美国农业初一地理题 gis在物流中的应用 一种甘蔗,600吨可以榨出96吨蔗糖现有这种甘蔗1050吨,可以榨出蔗糖多少吨? 题是这样的:b点在五带中的热带,在 气压带控制下.还有:1.一年中,5三个月是1南半球的春季 2北半球的冬季 3南半球的秋季 4北半球的秋季 b点在热带. 地理信息系统的应用 碳酸钠与硫酸钙的化学反应式 为什么红磷在验证空气中氧气含量时,红磷含量要过量 100W的太阳能电池板一般是多少A电流?12/24 碳酸钠和硫酸钙的离子方程式速度啊```````` 汽车刹车后作匀减速运动,最后停了下来,在刹车过程中,汽车前半程的平均速度与后半程的平均速度之比是?希望有准确的解释 我该把这份文件发给谁?英语怎么说给对方写e-mail的 我想知道高中生物书里面的 光合作用的方程式.还有有氧呼吸,无氧呼吸的方程式 英语翻译"中广核"三字,是否要翻译? 既能溶于水又能溶于酸的碱是A.Cu(OH)2 B.Na2CO3 C.CaCO3 D.NaOH 并且写出原因 有氧呼吸 无氧呼吸 光合作用的化学方程式与反应场所 复制党走啊
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘