[ES6深度解析]4:Template strings(模板字符串)
Posted MAX力出奇迹
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ES6深度解析]4:Template strings(模板字符串)相关的知识,希望对你有一定的参考价值。
撇号基础知识(`)
ES6引入了一种新的字符串字面量语法,称为模板字符串。它们看起来像普通的字符串,除了使用反勾字符ˋ
而不是通常的引号\'
或"
。在最简单的情况下,它们实际上只是字符串:
context.fillText(`Ceci n\'est pas une chaîne.`, x, y);
但这些字符串被称为“模板字符串”,而不是“没有任何特殊功能,只有反引号的乏味的普通字符串”是有原因的。模板字符串给javascript带来了简单的字符串插值。也就是说,它们是将JavaScript值插入字符串的一种漂亮、方便的方法。有无数种方法可以使用它,但最能温暖我心的是那句不起眼的错误信息:
function authorize(user, action) {
if (!user.hasPrivilege(action)) {
throw new Error(
`User ${user.name} is not authorized to do ${action}.`);
}
}
在这个例子中,${user.name}
和${action}
被称为模板替换。JavaScript将把值user.name
和action
插入到结果字符串中。
到目前为止,这只是+
操作符的一个稍微更好的语法,下面的细节是你所期望的:
- 模板替换中的代码可以是任何JavaScript表达式,因此允许函数调用、算术等。如果你愿意,甚至可以在另一个模板字符串中嵌套一个模板字符串,称之为模板初始化(template inception)
- 如果一个值都不是字符串,它将使用通常的规则转换为字符串。例如,如果
action
是一个对象,它的.tostring()
方法将被调用。 - 如果你需要在模板字符串中写一个反勾号,你必须用反斜杠来转义它:
\\ˋ
与"ˋ"
相同。 - 同样,如果你需要在模板字符串中包含两个字符
${
,你可以用反斜杠:\\${
或$\\{
转义字符。
与普通字符串不同,模板字符串可以包含多行:
$("#warning").html(`
<h1>Watch out!</h1>
<p>Unauthorized hockeying can result in penalties
of up to ${maxPenalty} minutes.</p>
`);
模板字符串中的所有空格,包括换行符和缩进符,都将一字不差地包含在输出中。
撇号的未来
让我们来谈谈模板字符串不能做的一些事情:
- 它们不会自动为您转义特殊字符。为了避免跨站点脚本漏洞(cross-site scripting),您仍然必须小心处理不可信的数据,就像连接普通字符串一样。
- 模板字符串不处理数字和日期的特定语言格式,更不用说复数格式了。
- 它们不是模板库的替代品,就像
Mustache
或Nunjucks
- 模板字符串没有任何用于循环的内置语法——例如,从数组中构建HTML表的行——甚至没有条件语句。
标记模板(tagged templates)
ES6在模板字符串上又做了一个改进,让JS开发人员和库设计人员能够解决这些限制等等。该特性称为标记模板(tagged templates)。
标记
模板的语法很简单。它们只是模板字符串,在开始的反引号之前有一个额外的标签。对于我们的第一个例子,标签将是SaferHTML
,我们将使用这个标签来尝试解决上面列出的第一个限制:自动转义特殊字符。
注意,SaferHTML
不是由ES6标准库提供的。我们将在下面自己实现它。
var message = SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;
这里的标记
是单一标识符SaferHTML
,但标记
也可以是一个属性,如SaferHTML.escape
,甚至是一个方法调用,如SaferHTML.escape({unicodeControlCharacters: false})
。(更准确地说,任何ES6的MemberExpression或CallExpression都可以作为标记
。)
我们看到,不带标记
模板字符串是简单字符串连接的简写形式。带标记
的模板是其他东西的简写:函数调用。
上面的代码相当于:
var message = SaferHTML(templateData, bonk.sender);
其中templateData
是模板中所有字符串部分的不可变数组,由JS引擎创建。在这里,数组将有两个元素,因为在标记模板中有两个字符串部分,由,
分隔。所以templateData
会像Object.freeze(["<p>"," has sent you a bonk.</p>"]
。
实际上在templateData
上还有一个属性。我们不会在本文中使用它,但是为了完整起见,我将提到它:templateData.raw
是另一个数组,包含了带标签的模板中的所有字符串部分,但这一次与它们在源代码中看到的完全一样——像\\n
这样的转义序列保持完整,而不是被转换成换行符等等。标准标记String.raw
使用这些原始字符串。
这使得SaferHTML函数
可以自由地以百万种可能的方式解释字符串和替换。
在继续阅读之前,您可能想要尝试弄清楚SaferHTML应该做什么,然后尝试自己实现它。毕竟,它只是一个函数。这里有一个可能的答案:
function SaferHTML(templateData) {
var s = templateData[0];
for (var i = 1; i < arguments.length; i++) {
var arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don\'t escape special characters in the template.
s += templateData[i];
}
return s;
}
本文来自博客园,作者:Max力出奇迹,转载请注明原文链接:https://www.cnblogs.com/welody/p/15167427.html
以上是关于[ES6深度解析]4:Template strings(模板字符串)的主要内容,如果未能解决你的问题,请参考以下文章