js模板字符串⾃定义类名_模板字符串_ES6笔记3
⼀.作⽤及语法
模板字符串⽤来实现字符串插值,⽐加号(+)拼接更⽅便更优雅
`${expr}`语法,提供了字符串插值功能
注意:上⾯的`(反撇号,位于键盘Esc下⾯)是模板字符串语法的⼀部分,⽽不是markdown⽤错了
P.S.笔者遇到了第⼀个问题,反撇号与markdown语法有冲突,有两种选择,要么使⽤markdown特性之多⾏反撇好作为代码分隔符(⽤两个连续反撇号包裹代码,但笔者使⽤的markdown插件不⽀持该罕见语法),要么使⽤code标签,⽐如上⾯的markdown源码是\`${expr}\`
例如:
function req(user, action) {
// if !isValid
error(`user ${user} failed to do action ${action}`);
}
function error(str) {
console.log(str);
}
// test
req('Sam', 'login'); // user Sam failed to do action login
⼆.特点
包括变量、字⾯量、函数调⽤等等,但不⽀持流程控制(分⽀/循环),所以模板字符串不能代替模板引擎
例如:
// 不⽀持分⽀/循环
// console.log(`${if (2 > 1) {str}}`); // Uncaught SyntaxError: Unexpected token if
// console.log(`${for (; false;) {}}`); // Uncaught SyntaxError: Unexpected token for
var outer = 'outer';
var inner = 'inner';
var str = `
\$\{
${
outer // 变量
+ // +拼接
`\$\{
${inner} // 插值
\}`
}
\}
`;
var h5 = document.querySelector('#h5');
var pre = document.querySelector('#pre');
h5.innerHTML = str;
pre.innerHTML = str;
显⽰结果如下:
// #h5
${ outer${ inner // 插值 } }
/
/ #pre
${
outer${
inner // 插值
}
}
3.可以分多⾏书写
但注释(单⾏/多⾏)可能会作⽤于整个串,或者直接作为字⾯量出现在结果串⾥。模板字符串中所有的空格、新⾏、缩进,都会原样输出在⽣成的字符串中(pre与其它元素不同),具体见上例
4.特殊字符需要转义
3个特殊字符[`${](正则表达式形式)需要转义,具体见上例
P.S.右花括号不需要转义,当然,转义它也没错。但是上⾯3个必须转义
5.没有⾃动处理
不会⾃动过滤不安全标签,也不会⾃动转义特殊字符,同样需要防⽌xss攻击,虽然提供了标签模板(tagged templates),但不很⽅便
例如:
// xss攻击
var userInput = '';
var input = document.querySelector('#input');
input.innerHTML = `⽤户输⼊:${userInput}`;
上⾯代码会⽣成⼀个链接,点击alert “xss attack”,通过标签模板可以对模板字符串进⾏⾃定义处理,⽐如滤掉不安全字符,如下:
// 定义模板标签
function myFilter(templateData) {
var aStr = templateData; // 被${}插值分割后的字符串数组
var aRaw = templateData.raw; // 未经转义的原字符串(\n)
var aVar = Array.prototype.slice.call(arguments, 1); // 插值变量数组
console.log(aStr);
console.log(aRaw);
console.log(aVar);
// filter vars
aVar.forEach(function(item, index, arr) {
arr[index] = place(/(]*>)/i, '');
});
var res = '';
var i = 0;
aStr.forEach(function(item) {
res += item;
if (aVar[i]) {
res += aVar[i++];
}
});
return res;
}
// 使⽤标签模板
var safeInput = document.querySelector('#safe_input');
safeInput.innerHTML = myFilter`⽤户输⼊:\n${userInput}`;
// 等价于
// safeInput.innerHTML = myFilter(['⽤户输⼊:'], userInput);
标签出现在模板字符串前,是⼀种简化的函数调⽤,模板标签类似于回调函数,参数templateData的格式是确定的,从参数中取出数据,处理完毕返回即可
但定义模板标签感觉还是⽐较⿇烦,但这是⼀个很有吸引⼒的特性,预⽰着⼀个强⼤的字符串处理库(转义特殊字符、i18n、字数统计等等)
6.灵活性
标签模板的返回值不⼀定是字符串,可以是任何值。这意味着不仅仅会出现⼀个强⼤的“字符串”处理库,任何库都可以以这种形式完美嵌⼊JS内,尤其是着⾊器语⾔这样的⽬前在JS中形式不太友好的东西……其它语⾔出现诱⼈的特性后,可以完美植⼊JS,甚⾄可以借此实现⼀种⾃⼰的语⾔(模板标签的函数体就是解释器)
标签模板带来很⼤的灵活性,可以⽤⾃定义的标签来创建正则表达式、DOM树、图⽚、以promises为代表的整个异步过程、JS数据结构、GL着⾊器……
引⽤参考资料中的原⽂:
标签模板以开放的姿态欢迎库设计者们来创建强有⼒领域特定语⾔。这些语⾔可能看起来不像JS,但是它们仍可以⽆缝嵌⼊到JS中并与JS 的其它语⾔特性智能交互。我不知道这⼀特性将会带领们⾛向何⽅,但它蕴藏着⽆限的可能性,这令我感到异常兴奋!
三.总结
模板字符串看似语法糖,其实是打开了⼀扇⼤门,表⽰JS以开放的姿态迎接未来
还记得前辈们5年前讨论的yield吗?那时候他们多希望有个这样的特性啊,讨论这个问题的初衷不就是希望JS能获得C#的yield特性吗?参考资料
《ES6 in Depth》:InfoQ中⽂站提供的免费电⼦书
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论