ES6学习笔记-模板字符串

Author Avatar
Splendour 11月 24, 2015

基础知识

  • 使用反撇号字符 ` 替代单引号和双引号,在最简单的情况下是一致的。

    console.log(`Hello ES6`);
    
  • 最常用法:字符串插值

    function authorize(user, action) {
    if (!user.hasPrivilege(action)) {
      throw new Error(
        `用户 ${user.name} 未被授权执行 ${action} 操作。`);
    }
    }
    

    其中,${user.name}和${action}被称为模板占位符

  • 模板占位符中的代码可以是任意表达式,甚至可以嵌套另一个模板字符串

  • 如果模板占位符不是字符串,则会按照常规转换为字符串。例如,如果 action 是一个对象,则会调用其 .toString() 方法

  • 如果需要输入 `,\$,{ 等字符,则需要加上反斜杠转义

  • 可以多行书写,所有空格、新行和缩进,都会原样输出在生成的字符串中

$('#warning').html(`
  <h1>小心!>/h1>
  <p>未经授权打冰球可能受罚
  将近${maxPenalty}分钟。</p>
`);

进阶知识

  • 不会自动转义特殊字符,需要手动防止 XSS 攻击
  • 无法很好地与国际化库配合
  • 标签模板:在模板字符串开始的反撇号前附加一个额外的标签即可。
    let message =
    SaferHTML`<p>${user.name} 向你示好。</p>`;
    
    这里用到的标签是一个标识符SaferHTML;也可以使用属性值作为标签,例如:SaferHTML.escape;还可以是一个方法调用,例如:SaferHTML.escape({unicodeControlCharacters: false})。精确地说,任何ES6的成员表达式(MemberExpression)或调用表达式(CallExpression)都可作为标签使用。

可以看出,无标签模板字符串简化了简单字符串拼接,标签模板则完全简化了函数调用!

下面是 SaferHTML 的一个方案(该方案仍有很大缺陷,在此仅仅举例说明)

let username = `splendour<script>alert('xss');</script>`;
let test = SaferHTML`${username} 向你示好`;
function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i in arguments) {
    if (i == 0) continue;
    let arg = String(arguments[i]);
    // 转义占位符中的特殊字符。
    s += arg.replace(/&/g, "&")
            .replace(/</g, "<")
            .replace(/>/g, ">");
    // 不转义模板中的特殊字符。
    s += templateData[i];
  }
  return s;
}

实现了该函数,就可以使用标签模板来简化代码了!