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, "&amp;") //将处理完的模板字符串放回去返回结果里面
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
    }
    //原例子的写法不太清晰,我改一下
    //在将大括号外的第二个元素保存到返回结果(即真正参数之后的数据)
    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>&lt;script&gt;alert("abc")&lt;/script&gt; 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"
}

参考引用:

  1. es6字符串扩展


线上猛如虎
2.2k 声望178 粉丝

你们都有梦想的,是吧.怀抱着梦想并且正朝着梦想努力的人,寻找着梦想的人,我想为这些人加油呐喊!