[ES6深度解析]4:Template strings(模板字符串)

时间:2021-08-20
本文章向大家介绍[ES6深度解析]4:Template strings(模板字符串),主要包括[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.nameaction插入到结果字符串中。

到目前为止,这只是+操作符的一个稍微更好的语法,下面的细节是你所期望的:

  • 模板替换中的代码可以是任何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),您仍然必须小心处理不可信的数据,就像连接普通字符串一样。
  • 模板字符串不处理数字和日期的特定语言格式,更不用说复数格式了。
  • 它们不是模板库的替代品,就像MustacheNunjucks
  • 模板字符串没有任何用于循环的内置语法——例如,从数组中构建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, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");

    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

本文来自博客园,作者:Max力出奇迹,转载请注明原文链接:https://www.cnblogs.com/welody/p/15167427.html

原文地址:https://www.cnblogs.com/welody/p/15167427.html