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等。但在学习和运用到项目中时,咱们须要注意如下两点:es6
ES6包含的是语法糖和语言、库的bug fix,对工程性问题没有太大的帮助;express
因为Traceur和Babel没法对ES6的全部特性进行完整高效的polyfill,所以咱们没法彻底享用ES6的各项特性。后端
最近接手一个项目的前端改造,正在尝试全新的技术栈(Riot+ES6+Glup+Webpack),本系列文章将做为理论+项目实践的笔记供往后查阅。浏览器
一言以蔽之,Template Strings就是让咱们减小字符串手工拼接的工做量。ecmascript
// Sample 1: 单行字符串拼接 var operand1 = 1 , 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> '
// Sample 1: 单行字符串拼接 var operand1 = 1 , 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>}
并非简单的占位符那么简单了。函数
${<expression>}
中可访问当前做用域所能访问到变量和函数var x = 1 (function(){ var y = 2 (function(b){ var tpl = `${x},${y},${a},${b}` // 结果是 "1,2,undefined,5" }(5)) var a = 3 let c = 4 // 因为采用let来声明c变量,所以不会发生variable hoist }())
${<expression>}
是即时计算(real-time computing)的,经过函数加壳可实现延迟计算(lazy evaluation)//real-time computing var tpl = `${x},${y}` var x = 1, y = 2 console.log(tpl) // "undefined, undefined" // lazy evaluation var tpl = ctx => `${ctx.x},${ctx.y}` console.log(tpl({x:1, y:2})) // "1, 2"
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函数
答案是否认的lua
缘由是经过正斜杠( \ )定义的多行字符串实际输出仍是一行字符串而已,但经过反引号( `` )定义的是真实的多行字符串,且经过换行符( \n )分隔每一行。spa
// 经过\定义多行的结果 <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, '')
从上文咱们了解到Template Strings是以总体为单位进行即时计算,也就是说留给咱们的自主操控能力是十分有限的。而Tagged Template Strings则大大加强了咱们的操控欲望。
其实Tagged Template Strings实质上是对Template Strings进行Tokenize操做,从而细化咱们的可操做粒度。而词法类型分为 字符串 和 表达式占位符的运算结果。
var x = 1, y = 2 var tpl = 'hello${x}:${y+1}' // Tokenize后的结果 var tokens = ['hello', 1, ':', 3, '']
具体玩法以下:
// 语法 <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 = 0, len = strings.length ; i < len; ++i) ret.push(strings.raw[i], vals[i] || '') return ret } // 定义Template Strings var x = 1, y =2 var ret = taggedFunc`\tHello${x}:${y+1}` console.log(ret) // 显示 "\tHello1:3" console.log(`\tHello${x}:${y+1}`) // 显示 " Hello1:3"
函数 有两个入参分别表明两类token。 {Array.} strings 为字符串类型的tokens,而 {...Any} vals 则为表达式占位符运算结果tokens。
而须要注意的是: strings.length === vals.length + 1
另外咱们看到最后两行代码会发现 `\tHello${x}:${y+1}` 中的制表符将在输出结果中起效,而通过Tagged Function处理的则按普通字符输出而已。其实这是经过 {Array.<DOMString>}strings.raw属性
操做strings中token的结果,也就是说strings.raw属性将对控制符进行转义从而实现按照普通字符输出。
其做用与上述的taggedFunc同样,就是将按普通字符输出Template Strings中的控制符。
// 下面的hashTemplate函数 // 是一个自定义的模板处理函数 var libraryHtml = hashTemplate` <ul> #for book in ${myBooks} <li><i>#{book.title}</i> by #{book.author}</li> #end </ul> `;
本人以为这种用法不可取,Tagged Function原本就按照自身规则对模板进行Tokenize,而后咱们在此基础上对结果进行二次Tokenize,那还不如直接按本身定义的规则来作词法分析更省心。
Template Strings和Tagged Template Strings 都可经过Traceur和Babel作transpile,因此咱们如今就能够撸起了,开干吧各位!
http://es6.ruanyifeng.com/#docs/string
http://www.sitepoint.com/understanding-ecmascript-6-template-strings/