资讯专栏INFORMATION COLUMN

ES6 Features系列:Template Strings & Tagged Templ

MyFaith / 2016人阅读

摘要:由两部分组成模板起始符,称为沉音符反引号,其内容被识别为字符串模板。其实这是通过属性操作中的结果,也就是说属性将对控制符进行转义从而实现按照普通字符输出。的语法是紧跟在后面,两者间不能有空格或制表符等。

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等。但在学习和运用到项目中时,我们需要注意以下两点:

ES6包含的是语法糖和语言、库的bug fix,对工程性问题没有太大的帮助;

由于Traceur和Babel无法对ES6的所有特性进行完整高效的polyfill,因此我们无法完全享用ES6的各项特性。

最近接手一个项目的前端改造,正在尝试全新的技术栈(Riot+ES6+Glup+Webpack),本系列文章将作为理论+项目实践的笔记供日后查阅。

2. What is Template Strings?

一言以蔽之,Template Strings就是让我们减少字符串手工拼接的工作量。

2.1. Before ES6
// 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 = "

" + "" + name + "" + "
" var tpl2 = " "
2.2. Embracing ES6
// Sample 1: 单行字符串拼接
var operand1 = 1
  , operand2 = 2.1
var tpl1 = `${operand1}+${operand2}~=${parseInt(operand1+operand2)}`

// Sample 2: 多行字符串拼接
var name = "fsjohnhuang"
  , id = "region"
var tpl1 = ``

假若了解过CoffeeScript,那么会发现ES6的Template Strings怎么这么眼熟。Template Strings由两部分组成:
1. 模板起始符—— ``,称为沉音符/反引号(grave accent),其内容被识别为字符串模板。
2. 表达式占位符—— ${}为JavaScript的有效表达式(如 name, 1==2等),因此 ${} 并不是简单的占位符那么简单了。

2.3. Cautions 1. ${} 中可访问当前作用域所能访问到变量和函数
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
}())
2. ${} 是即时计算(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"
3. 多行陷阱(pitfall of multiline),在编写HTML模板时我习惯如下写法
var tpl = "

${title}

${subtitle}
" // 然后是模板引擎解析tpl

那现在是否就可以毫无顾虑地改用Template Strings呢?

var tpl = ctx => `

${ctx.title}

${ctx.subtitle}
` // 直接调用tpl函数

答案是否定的

原因是通过正斜杠( )定义的多行字符串实际输出还是一行字符串而已,但通过反引号( `` )定义的是真实的多行字符串,且通过换行符( )分隔每一行。

// 通过定义多行的结果


${ctx.title}

${ctx.subtitle}
// 通过反引号定义多行的结果

${ctx.title}

${ctx.subtitle}

那么当使用jQuery将反引号定义的HTML模板来生产DOM元素时就会直接报错了,这时我们需要删除这些控制字符。

var removeCtlChar = raw => raw.replace(/[
	vf]/ig, "")
3. What is Tagged Template Strings?

从上文我们了解到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, ""] 

具体玩法如下:

// 语法