ES6 引入了一种新型的字符串字面量语法,称为模板字符串(template strings)。使用反撇号(`)来代替普通字符串的引号。下面是一个例子:
let greeting = `Hello Jackie`!
有什么用呢?模板字符串为 JavaScript 提供了简单的插值功能(string interpolation)。例:
let name = "Jackie";
let greeting = `Hello ${name}`!
${name}
称为占位符(placeholder)。模板占位符可以是任意 JavaScript 表达式,比如函数调用、算数运算等,都可以作为占位符使用,甚至可以嵌套另一个模板字符串。
如果占位符计算出的值不是字符串,那么会调用 toString
方法。
如果要书写反撇号(`
),或者 $
,或者 {
,都需要转义(加反斜杠)。
与普通字符串的一大区别是,模板字符串可以多行书写:
$("#warning").html(`
<h1>你好!</h1>
<p>我叫${name}。这是一个多行
模板字符串的
示例。</p>
`);
所有的空格、新行、缩进,都会原样输出在生成的字符串中。
但是,模板字符串并不会自动转义 HTML 字符(比如 <
>
等),而且,不支持条件语句、遍历,比其他的模板库还是弱了些。为了突破这些限制,ES6 提供了标签模板(tagged templates)。只需要在起始的反撇号前加上一个额外的标签,如下面的 htmlspecial
:
var message = htmlspecial`<p>${htmlStr}</p>`;
上面的代码等效于
var message = htmlspecial(templateData, htmlStr);
templateData
是一个不可变数组,存储着模板所有的字符串部分,也就是除去占位符以后剩下的部分,比如上例中 ${htmlStr}
将模板分割为两部分,所以 templateData
数组内就是两个元素,形如 ["<p>", "</p>"]
。同时这个数组是不能更改的,相当于用了 Object.freeze
。
htmlspecial
的一种实现(用来将 <
>
等特殊字符转义为实体引用):
function htmlspecial(templateData) {
var s = templateData[0];
for (var i = 1; i < arguments.length; i++) {
var arg = String(arguments[i]);
// 转义HTML特殊字符。
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// 拼接
s += templateData[i];
}
return s;
}
函数返回的值就会当作模板字符串的输出。