反撇号(`)基础知识
ES6中引入了一种新型的字符串字面量语法,称为模板字符串(template strings).除了使用反撇号字符 ` 代替普通字符串的" '外,他们看起来与普通字符串并无二致,在最简单的情况下与普通字符串表现一致。
context.fillText(`Ceci n'est pas une chaîne.`, x, y);
但它并不是“被反撇号括起来的普通字符串”,它是一种字符串插值。
//模板字符串的错误提示
function authorize(user, action) {
if (!user.hasPrivilege(action)) {
throw new Error(
`用户 ${user.name} 未被授权执行 ${action} 操作。 `);
}
}
在这个例子中,${user.name}和${action}称为模板占位符。JavaScript将把user.name和action插入到最终生成的字符串中。
模板占位符中的代码可以是任意 JavaScript 表达式,所以函数调用、算数运算等这些都可以作为占位符使用,你甚至可以在一个模板字符串中嵌套另一个,我称之为模板套构(template inception)
若输入的值不是字符串则可以通过。toString();转换为字符串值。
如果你需要在模板字符串中书写反撇号,你必须使用反斜杠将其转义: `\``等价于"`"。以此类推,引入$和{需要使用反斜杠\ 对字符进行转义 :'\$' 和'\{';而且模板字符串可以多行书写:
$("#myTemplateStrings").html(`
<h1> 模板字符串${name}</h1>
<p>这是一个跨行模板字符串示例
${templateStrings}</p>
`);
其中所有的空格、换行、递进都会原样输出在生成的字符串中。
反撇号的未来
- 不会为你自动转义特殊字符,为避免跨站脚本漏洞(XSS),需要像拼接普通字符串时那样对非置信数据进行特殊处理。
- 无法很好地与国际化库(可以帮助你面向不同用户提供不同的语言)相配合,模板字符串不会格式化特定语言的数字和日期,更别提同时使用不同语言的情况了。(i18n)
- 它们不能替代模板引擎的地位,例如: Mustache、 Nunjucks 一部分原因是在模板字符串没有内建的循环或条件语句语法。我们一起来看如何解决这个问题,如果 JS 不提供这个特性,我们就写一个标签来提供相应支持。
// 基于纯粹虚构的模板语言 // ES6 标签模板。 var libraryHtml = hashTemplate` <ul> #for book in ${myBooks} <li><i>#{book.title}</i> by #{book.author}</li> #end </ul> `;
- 模板字符串没有内建循环语法,所以你无法通过遍历数组来构建类似 HTML 中的表格,甚至它连条件语句都不支持。模板套构的方法比较愚钝。
- ES6 为 JS 开发者和库设计者提供了一个很好的衍生工具,你可以借助这一特性突破模板字符串的诸多限制,我们称之为标签模板(tagged templates)。
使用上只需要在模板字符串反撇号前附加一个额外的标签即可。例子:var message = SafeHTML`<p>${bonk.sender}say hello to you.</p>`;
任何ES6的成员表达式(MemberExpression)或者通用表达式(CallExpression)都可以作为标签使用。上面代码等效于
var message = SafeHTML(templateData,bonk.sender);
templateData是一个不可变数组,存储着模板所有的字符串部分,由JS引擎创建。因为占位符将标签模板分为两个字符串的部分,所以这个数组包含两个元素。
function SaferHTML(templateData) { var s = templateData[0]; for (var i = 1; i < arguments.length; i++) { var arg = String(arguments[i]); // 转义占位符中的特殊字符。 s += arg.replace(/&/g, "&") .replace(/</g, "<") .replace(/</g, ">"); // 不转义模板中的特殊字符。 s += templateData[i]; } return s; }
SafeHTML需要通过不同的方式将HTML不同部分的特殊字符转义,SafeHTML就无法做到全部转义。
我什么时候可以开始使用这一特性
服务器端io.js 支持ES6 客户端 Firefox和Chrome都支持