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/