模板字面量 是允许嵌入表达式的字符串字面量。
你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串”。
语法
`string text`
?
`string text line 1
string text line 2`
?
`string text ${expression} string text`
?
tag `string text ${expression} string text`
描述
模板字符串使用反引号 () 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。
`\`` === "`" // --> true
多行字符串
在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:
console.log(‘string text line 1\n‘ +
‘string text line 2‘);
// "string text line 1
// string text line 2"
要获得同样效果的多行字符串,只需使用如下代码:
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
插入表达式
在普通字符串中嵌入表达式,必须使用如下语法:
var a = 5;
var b = 10;
console.log(‘Fifteen is ‘ + (a + b) + ‘ and\nnot ‘ + (2 * a + b) + ‘.‘);
// "Fifteen is 15 and
// not 20."
现在通过模板字符串,我们可以使用一种更优雅的方式来表示:
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
嵌套模板
在某些时候,嵌套模板是具有可配置字符串的最简单也是更可读的方法。 在模板中,只需在模板内的占位符 ${ }内使用它们,就可以轻松地使用内部反引号。 例如,如果条件 a 是真的,那么返回这个模板化的文字。
一个普通字符串例子:
var classes = ‘header‘
classes += (false ?
‘‘ : true ?
‘ icon-expander‘ : ‘ icon-collapser‘);
输出:header icon-expander
在ES2015中使用模板文字而没有嵌套:
var classes = `header ${ false ? ‘‘ :
(true ? ‘icon-expander‘ : ‘icon-collapser‘) }`;
输出:header icon-expander
在ES2015的嵌套模板字面量中:
var classes = `header ${ false ? ‘‘ :
`icon-${true ? ‘icon-expander‘ : ‘icon-collapser‘}` }`;
输出:header icon-icon-expander
带标签的模板字符串
更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西, 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。
var person = ‘Mike‘;
var age = 28;
?
function myTag(strings, personExp, ageExp) {
?
var str0 = strings[0]; // "that "
var str1 = strings[1]; // " is a "
?
// There is technically a string after
// the final expression (in our example),
// but it is empty (""), so disregard.
// var str2 = strings[2];
?
var ageStr;
if (ageExp > 99){
ageStr = ‘centenarian‘;
} else {
ageStr = ‘youngster‘;
}
?
return str0 + personExp + str1 + ageStr;
?
}
?
var output = myTag`that ${ person } is a ${ age }`;
?
console.log(output);
// that Mike is a youngster
标签函数并不一定需要返回一个字符串。可以返回其他数据类型,比如数组、json等
原始字符串
在标签函数的第一个参数中,存在一个特殊的属性raw,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。
function tag(strings) {
console.log(strings.raw[0]);
}
?
tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2"
另外,使用String.raw()方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。
var str = String.raw`Hi\n${2+3}!`;
// "Hi\n5!"
?
str.length;
// 6
?
str.split(‘‘).join(‘,‘);
// "H,i,\,n,5,!"
研究了一下,其实模板字符串中的占位符${expression}相当于分隔符,将模板字符串分割,
function tag(strings) {
console.log(strings.raw[0]);
?
console.log(strings.raw[1]);
?
console.log(strings.raw[2]);
}
?
tag`${document.cookie}`;
//0,1都是空,3是undefined
tag`aaa${document.cookie}`;
//0是aaa,1是空,3是undefined
tag`aaa${document.cookie}bbb`;
//0是aaa,1是bbb,3是undefined
tag`aaa${document.cookie}bbb${document}ccc`;
//0是aaa,1是bbb,3是ccc
从上面例子可以看出占位符${expression}相当于分隔符,将模板字符串分割。
带标签的模板字面量及转义序列
自ES2016起,带标签的模版字面量遵守以下转义序列的规则:
Unicode字符以"\u"开头,例如\u00A9
Unicode码位用"\u{}"表示,例如\u{2F804}
十六进制以"\x"开头,例如\xA9
八进制以""和数字开头,例如\251
注:八进制好像不管用
参考资料