es6学习笔记-字符串模板_v1.0
实例:模板编译
//先组成一个模板
var template = `
<ul>
<% for(var i=0; i < data.supplies.length; i++) { %> //使用<%...%>放置JavaScript代码
<li><%= data.supplies[i] %></li> //使用<%= ... %>输出JavaScript表达式。
<% } %>
</ul>
`;
//这是编译模板的函数,将模板编译写js可运行的脚本
function compile(template){
//正则规则,匹配<%=和%>之间的字符串,这个字符串里面包括零个或任意个字符(.+?),并且捕获,全局匹配
var evalExpr = /<%=(.+?)%>/g;
//正则规则,匹配<%和%>之间的字符串,这个字符串里面包括1个或多个空白符或非空白符或者什么都没有,并且捕获,全局匹配
var expr = /<%([\s\S]+?)%>/g;
template = template
//先处理js表达式,将<%=和%>之间的字符串进行替换
.replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
//然后再处理js代码,将<%和%>之间的字符串进行替换
.replace(expr, '`); \n $1 \n echo(`');
//然后再用括号包起来,注意里面有反引号
template = 'echo(`' + template + '`);'; //注意这里已经是被标上了echo方法了,跟下面echo函数对应
var script = //这里直接用反引号包起来
`(function parse(data){
var output = "";
function echo(html){ //声明了echo函数
output += html;
}
${ template } //直接解析并且执行里面的函数,并且调用到上面设置的echo函数进行处理
return output;
})`;
return script;
}
----------------------------------------------
//这是编译函数处理后返回的script,变成了可执行的js代码
echo('<ul>');
for(var i=0; i < data.supplies.length; i++) {
echo('<li>');
echo(data.supplies[i]);
echo('</li>');
};
echo('</ul>');
//在使用的时候,先生成js代码
var parse = eval(compile(template));
//然后执行这个js代码,其实就是将参数传给编译后的js代码进行运行
console.log(parse({ supplies: [ "broom", "mop", "cleaner" ] }));
标签模板
模板字符串紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。
alert`123` //alert是函数(也就是所谓的标签),`123`是模板字符串
// 等同于
alert(123)
"标签"的第一个参数是个数组,数组的内容是模板字符串中除了大括号表达式以外的内容。从第二个参数起就是大括号表达式计算的结果
//tag是一个自定义函数
let tag = function(stringArr, value1, value2){
console.log(stringArr); //[ 'Hello ', ' world ', '' ],是一个数组
console.log(value1);//15,是大括号运算后的结果,即模板字符串解析后的结果,a+b =15
console.log(value2);//50,类似
}
let a = 5;
let b = 10;
//这个tag是一个函数
tag`Hello ${ a + b } world ${ a * b }`;
//根据tag函数分析的参数,其实相当于以前的这种传参
tag(['Hello ', ' world ', ''], 15, 50)
tag函数的第一个参数是一个数组,该数组的成员是模板字符串中那些没有变量替换的部分,也就是说,变量替换只发生在数组的第一个成员与第二个成员之间、第二个成员与第三个成员之间,以此类推。
tag函数的其他参数,都是模板字符串各个变量被替换后的值。由于本例中,模板字符串含有两个变量,因此tag会接受到value1和value2两个参数。
再看另外一个例子熟悉一下:
真正的参数还是会用arguments
需要了解第一个参数是数组的使用方式
let passthru = function(literals) {//这里是一个数组
let result = '';
let i = 0;
while (i < literals.length) { //通过遍历这个数组
result += literals[i++];//这是保存非模板字符串的(大括号的)
//console.log(result); // 如果分别打印result就会发现他的过程
if (i < arguments.length) {//获取模板字符串解析之后的真正参数
result += arguments[i]; //这是模板字符串解析之后的(大括号内的内容,即${total}之类的)
//console.log(result); // 如果分别打印result就会发现他的过程
}
}
return result;
}
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
console.log(msg) // "The total is 30 (31.5 with tax)"
过滤HTML字符串,防止用户输入恶意内容
let SaferHTML = function (templateData) {
let s = templateData[0];//先将大括号外的第一个元素保存起来(即真正的参数之前的数据)
for (let i = 1; i < arguments.length; i++) { //对于大括号内的进行遍历处理
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&") //将处理完的模板字符串放回去返回结果里面
.replace(/</g, "<")
.replace(/>/g, ">");
}
//原例子的写法不太清晰,我改一下
//在将大括号外的第二个元素保存到返回结果(即真正参数之后的数据)
s += templateData[1];//
return s;
}
let sender = '<script>alert("abc")</script>'; // 恶意代码
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
console.log(message)
//返回<p><script>alert("abc")</script> has sent you a message.</p>
多语言转换(国际化处理)。
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"
没有详细函数写法,只是说明一个用途
String.raw()
tag函数的第一个参数strings,有一个raw属性,也指向一个数组。该数组的成员与strings数组完全一致
tag`First line\nSecond line`
function tag(strings) {
console.log(strings.raw[0]);
// "First line\\nSecond line"
}
参考引用:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。