ES6 Features系列:Template Strings & Tagged Template Strings
1. Brief
ES6(ECMAScript 6th edition)于2015年7月份发布,虽然各大浏览器仍未全面支持ES6,但我们可以在后端通过Node.js 0.12和io.js,而前端则通过Traceur或Babel这类Transpiler将ES6语法预转译为ES5语法,来提前兴奋一把。而仅需适配IE9+的朋友们现在更是可以开始撸ES6了,而不必为学哪门JavaScript超集语言而烦恼。(ES6又名为ECMAScript 2015或JavaScript.next,ES4的部分较为激进的特性被调用到该版本中实现。)
ES6带给我们很多惊喜,如class、module、export和import等。但在学习和运用到项目中时,我们需要注意以下两点:
1. ES6包含的是语法糖和语言、库的bug fix,对工程性问题没有太大的帮助;
2. 由于Traceur和Babel无法对ES6的所有特性进行完整高效的polyfill,因此我们无法完全享用ES6的各项特性。
最近接手一个项目的前端改造,正在尝试全新的技术栈(Riot+ES6+Glup+Webpack),本系列文章将作为理论+项目实践的笔记供日后查阅。
2. What is Template Strings?
一言以蔽之,Template Strings就是让我们减少字符串手工拼接的工作量。
2.1. Before ES6
// Sample 1: 单行字符串拼接
var operand1 =
, operand2 = 2.1
var tpl1 = operand1 + ' + ' + operand2 + '~=' + parseInt(operand1+operand2)
var tpl2 = [operand1, ' + ' , operand2, '~=', parseInt(operand1 + operand2)].join('')
// Sample 2: 多行字符串拼接
var name = 'fsjohnhuang'
, id = 'region'
var tpl1 = '<div id="' + id + '">'
+ '<a>' + name + '</a>'
+ '</div>'
var tpl2 = '<div id=" ' + id + ' ">\
<a>' + name + '</a>\
</div>'
2.2. Embracing ES6
// Sample 1: 单行字符串拼接
var operand1 =
, operand2 = 2.1
var tpl1 = `${operand1}+${operand2}~=${parseInt(operand1+operand2)}`
// Sample 2: 多行字符串拼接
var name = 'fsjohnhuang'
, id = 'region'
var tpl1 = `<div id="${id}">
<a>${name}</a>
</div>`
假若了解过CoffeeScript,那么会发现ES6的Template Strings怎么这么眼熟。Template Strings由两部分组成:
1. 模板起始符—— `` ,称为沉音符/反引号(grave accent),其内容被识别为字符串模板。
2. 表达式占位符—— ${<expression>} ,<expression>为JavaScript的有效表达式(如 name, 1==2等),因此 ${<expression>} 并不是简单的占位符那么简单了。
2.3. Cautions
1. ${<expression>} 中可访问当前作用域所能访问到变量和函数,如
var x = (function(){
var y =
(function(b){
var tpl = `${x},${y},${a},${b}` // 结果是 "1,2,undefined,5"
}())
var a =
let c = // 由于采用let来声明c变量,因此不会发生variable hoist
}())
2. ${<expression>} 是即时计算(real-time computing)的,通过函数加壳可实现延迟计算(lazy evaluation)
//real-time computing
var tpl = `${x},${y}`
var x = , y =
console.log(tpl) // "undefined, undefined" // lazy evaluation
var tpl = ctx => `${ctx.x},${ctx.y}`
console.log(tpl({x:1, y:2})) // "1, 2"
3. 多行陷阱(pitfall of multiline),在编写HTML模板时我习惯如下写法
var tpl = '<div>\
<h3>${title}</h3>\
<span>${subtitle}</span>\
</div>'
// 然后是模板引擎解析tpl
那现在是否就可以毫无顾虑地改用Template Strings呢?
var tpl = ctx => `<div>
<h3>${ctx.title}</h3>
<span>${ctx.subtitle}</span>
</div>`
// 直接调用tpl函数
答案是否定的
原因是通过正斜杠( \ )定义的多行字符串实际输出还是一行字符串而已,但通过反引号( `` )定义的是真实的多行字符串,且通过换行符( \n )分隔每一行。
// 通过\定义多行的结果
<div> <h3>${ctx.title}</h3> <span>${ctx.subtitle}</span> </div> // 通过反引号定义多行的结果
<div>\n
<h3>${ctx.title}</h3>\n
<span>${ctx.subtitle}</span>\n
</div>
那么当使用jQuery将反引号定义的HTML模板来生产DOM元素时就会直接报错了,这时我们需要删除这些控制字符。
var removeCtlChar = raw => raw.replace(/[\r\n\t\v\f]/ig, '')
3. What is Tagged Template Strings?
从上文我们了解到Template Strings是以整体为单位进行即时计算,也就是说留给我们的自主操控能力是十分有限的。而Tagged Template Strings则大大增强了我们的操控欲望。
其实Tagged Template Strings实质上是对Template Strings进行Tokenize操作,从而细化我们的可操作粒度。而词法类型分为 字符串 和 表达式占位符的运算结果。
var x = , y =
var tpl = 'hello${x}:${y+1}' // Tokenize后的结果
var tokens = ['hello', , ':', , '']
具体玩法如下:
// 语法
<Tagged Function><Template Strings> /** Sample **/
/* 定义<Tagged Function>
* @param {Array.<DOMString>} strings - 字符串类型的tokens
* @param {...Any} vals - 表达式占位符的运算结果tokens
* @returns {Any}
*/
var taggedFunc = (strings, ...vals){
var ret = []
for(let i = , len = strings.length ; i < len; ++i)
ret.push(strings.raw[i], vals[i] || '')
return ret
} // 定义Template Strings
var x = , y =
var ret = taggedFunc`\tHello${x}:${y+}`
console.log(ret) // 显示 "\tHello1:3"
console.log(`\tHello${x}:${y+}`) // 显示 " Hello1:3"
<Tagged Function>函数 有两个入参分别代表两类token。 {Array.<DOMString>} strings 为字符串类型的tokens,而 {...Any} vals 则为表达式占位符运算结果tokens。
而需要注意的是: strings.length === vals.length +
另外我们看到最后两行代码会发现 `\tHello${x}:${y+}` 中的制表符将在输出结果中起效,而经过Tagged Function处理的则按普通字符输出而已。其实这是通过 {Array.<DOMString>}strings.raw属性 操作strings中token的结果,也就是说strings.raw属性将对控制符进行转义从而实现按照普通字符输出。
3.1. 内置的Tagged Function——String.raw
其作用与上述的taggedFunc一样,就是将按普通字符输出Template Strings中的控制符。
3.2. Cautions
1. Tagge Template Strings的语法是Template Strings紧跟在Tagged Function后面,两者间不能有空格或制表符等。
2. vals是运算后的实际值,若要延迟计算依然需要加壳。
3. @ruanyifeng老师说可通过Tagged Function来自定义带流程控制的模板语言
// 下面的hashTemplate函数
// 是一个自定义的模板处理函数
var libraryHtml = hashTemplate`
<ul>
#for book in ${myBooks}
<li><i>#{book.title}</i> by #{book.author}</li>
#end
</ul>
`;
本人觉得这种用法不可取,Tagged Function本来就按照自身规则对模板进行Tokenize,然后我们在此基础上对结果进行二次Tokenize,那还不如直接按自己定义的规则来做词法分析更省心。
4. Conclusion
Template Strings和Tagged Template Strings 均可通过Traceur和Babel做transpile,所以我们现在就可以撸起了,开干吧各位!
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4601200.html 肥子John^_^
5. Thanks
http://es6.ruanyifeng.com/#docs/string
http://www.sitepoint.com/understanding-ecmascript-6-template-strings/
ES6 Features系列:Template Strings & Tagged Template Strings的更多相关文章
- ES6特性-带标签的模板字符串(tagged template)
tagged template: 加在模板字符串前面加一个标签(函数). let dessert = = '甜品' drink = '茶' let breakfast = kitchen`今天的早餐是 ...
- 【探秘ES6】系列专栏(一):ES6简介
摘要:新一代JavaScript标准,ES6即将发布.[探秘ES6]系列专栏将一一剖析ES6的诸多新特性,让Web开发者对此有清晰全面的了解.本文为系列的第一篇,带你了解ES6到底是什么以及有哪些令人 ...
- 设计模式Template Method模式(Template Method)摘录
23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化托付给还 ...
- exception processing, template error resolving template
错误信息:Exception processing template “/view/df”: Error resolving template “/view/df”, template might n ...
- org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/home/index2", template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/home/index2", ...
- golang 模板 html/template与text/template
html模板生成: html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用t ...
- 设计模式总结篇系列:模板方法模式(Template Method)
模板方法模式需要开发抽象类和具体子类之间的协作.抽象类负责给出一个算法的轮廓和骨架,子类则负责给出这个算法的各个逻辑步骤.代表这些具体逻辑步骤的方法称做基本方法(primitive method):而 ...
- ES6笔记系列
ES6,即ECMAScript 6.0,ES6的第一个版本是在2015年发布的,所以又称作ECMAScript 2015 如今距ES6发布已经一年多的时间,这时候才去学,作为一个JSer,羞愧羞愧,还 ...
- ES6入门系列三(特性总览下)
0.导言 最近从coffee切换到js,代码量一下子变大了不少,也多了些许陌生感.为了在JS代码中,更合理的使用ES6的新特性,特在此对ES6的特性做一个简单的总览. 1.模块(Module) --C ...
随机推荐
- Linux搭建Scrapy爬虫集成开发环境
安装Python 下载地址:http://www.python.org/, Python 有 Python 2 和 Python 3 两个版本, 语法有些区别,ubuntu上自带了python2.7. ...
- java实现输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
package JingDian; import java.util.Scanner; public class charKind { public static void main(String[] ...
- 谈谈设计模式~原型模式(Prototype)
返回目录 原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例(clone),而不是新建(new)实例.被复制的实例就是我们所称的“原型”,这个原型是可定制的. 原型模式 ...
- Node.js与Sails~Model和ORM的持久化
回到目录 上一讲说了在sails里定义model及相关参数的说明,这一讲主要说一下如何将你的Model持久化到文件,关系数据库和Nosql数据库里,在持久化这点上,sails是统一管理的,它可以在/c ...
- 手把手教你在VirtualBox中与主机共享文件夹
安装VirtualBox为了共享文件夹,折腾了一晚上!网上的很多资料都不是很全面,这里就全面的总结一下,如果有其他的疑问,可以留言多多交流. VirtualBox下载地址,版本为5.1.2 设置共享文 ...
- Atitit 数据存储的分组聚合 groupby的实现attilax总结
Atitit 数据存储的分组聚合 groupby的实现attilax总结 1. 聚合操作1 1.1. a.标量聚合 流聚合1 1.2. b.哈希聚合2 1.3. 所有的最优计划的选择都是基于现有统计 ...
- Atitit 拦截数据库异常的处理最佳实践
Atitit 拦截数据库异常的处理最佳实践 需要特殊处理的ex 在Dao层异常转换并抛出1 Server层转换为业务异常1 需要特殊处理的ex 在Dao层异常转换并抛出 } catch (SQLExc ...
- 百度面试题 字符串相似度 算法 similar_text 和页面相似度算法
在百度的面试,简直就是花样求虐. 首先在面试官看简历的期间,除了一个自己定义字符串相似度,并且写出求相似度的算法. ...这个确实没听说过,php的similar_text函数也是闻所未闻的.之前看s ...
- iOS-推送通知详解
这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...
- html5 浏览器端数据库
为什么使用浏览器端数据库:随着浏览器的处理能力不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少用户等待从服务器获取数据的时间. 一.localStorage — 本地存储 可 ...