ES6学习笔记-模板字符串
基础知识
使用反撇号字符 ` 替代单引号和双引号,在最简单的情况下是一致的。
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 攻击
- 无法很好地与国际化库配合
- 标签模板:在模板字符串开始的反撇号前附加一个额外的标签即可。
这里用到的标签是一个标识符SaferHTML;也可以使用属性值作为标签,例如:let message = SaferHTML`<p>${user.name} 向你示好。</p>`;
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;
}
实现了该函数,就可以使用标签模板来简化代码了!