ES6 標籤模板

標籤模板其實不是模板,而是函數調用的一種特殊形式。「標籤」指的是函數,緊跟在後面的模板字符串就是它的參數。html

var a = 5;
var b = 10;
tag `Hello ${a+b} world ${a*b}`;
//這個標識名tag,它是一個函數。整個表達式的返回值,就是tag函數處理模板字符串以後的返回值。函數tag會依次接收到多個參數。

tag函數的第一個參數是一個數組,該數組的成員時模板字符串中那些沒有變量替換的部分,也就是說,變量替換隻發生在數組的第一個成員和第二個成員之間,以此類推。tag函數的其餘參數都是模板字符串各個變量被替換後的值,因爲本例中,模板字符串含有兩個變量,所以tag會接收到value1和value2兩個參數。
tag函數全部參數的實際值以下:
——第一個參數:['Hello ',' world ','']
——第二個參數:15
——第三個參數:50
也就是說tag函數其實是如下面的形式調用的
tag(['Hello ',' world ',''],15,50);
咱們能夠按照須要編寫tag 函數的代碼。數組

var a = 5;
var b = 10;

function tag(s,v1,v2){
    console.log(s[0]);
    console.log(s[1]);
    console.log(s[2]);
    console.log(v1);
    console.log(v2);
    return "ok";
}
tag`Hello ${a+b} world ${a*b}`;
//"Hello "
//" world "
//""
//15
//50
//"ok"

下面是一個更復雜的例子瀏覽器

var total = 30;
var msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals){
    var result = "";
    var i = 0;

    while (i<literals.length){
        result += literals[i++]; literals這個數組包括的是模板字符串中那些沒有變量替換的部分,也就是The total is,(,with tax).
        if(i<arguments.length){
            result+=arguments[i]; //arguments這個數組包括的是所有的參數,由於執行到這裏的時候,i已經加1,因此result鏈接的是模板字符串各個變量被替換後的值。也就是這裏的30,31.5
        }
    }
    return result;
}
msg //"The total is 30 (31.5 with tax)"
//上面這個例子展現瞭如何將各個參數按照原來的位置拼回去
//passthru函數採用rest參數的寫法以下
function passthru(literals,...values){
    var output ="";
    for(var index = 0;index<values.length;index++){
        output = literals[index]+values[index];
    }
    output+=literals[index];
    return output;
}

標籤模板的一個重要應用,就是過濾HTML字符串,防止用戶輸入惡意內容

function SaferHTML(templateData){
    var s = templateData[0];
    var i;
    for(i = 1;i<arguments.length;i++){
        var arg = String(arguments[i]);

        //sender裏面可能有特殊字符,進行轉義
        s += arg.replace(/&/g,"&amp;")
                .replace(/</g,"&lt;")
                .replace(/>/g,"&gt;");
        s += templateData[i];
    }
    console.log(i);//2,表示這個循環只執行了一次,由於templateData[0]="<p>",arguments這個數組只有${sender}這個元素,後面一長串字符都是templateData[2];
    return s;
}
var sender = '<script>alert("abc")</script>';
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;
console.log(message);

var total = 30;
var msg = passthru`The total is ${total}${total*1.05} with tax)`;
function passthru(literals){
    var result = "";
    var i = 0;
    while (i<literals.length){
        console.log(arguments[i]);
        // console.log(literals[i++]);
        result += literals[i++];
        if(i<arguments.length){
            result+=arguments[i];
            // console.log(arguments[i]);
        }
    }
    return result;
}
console.log(msg);

標籤模板的另外一個應用是多語言轉換(國際化處理)

var book = {
    title:"shiji",
    author:"simaqian"
};
var book1 = {
    title:"sanguo",
    author:"luo"
};
var myBooks = [book,book1];
function hashTemplate(templateData){
    var s = "";
    var i = 0;
    while(i<templateData.length){
        s += templateData[i++];
        if(i<arguments.length){
            s += arguments[i];
        }
    }
    return s;
}
var libraryHtml = hashTemplate`
    <ul>
        #for book in ${myBooks}
            <li><i>${book.title}</i> by ${book.author}</li>
        #end
    </ul>
`;
console.log(libraryHtml);

模板處理函數的第一個參數(模板字符串數組)還有一個raw屬性

在谷歌瀏覽器中,運行出來,仍是自己,沒有變化。函數

String.raw()

ES6還爲原生的String對象提供了raw方法
String.raw方法每每用來充當模板字符串的處理函數,返回一個反斜線都被轉義(即反斜線前面再加一個反斜線)的字符串,對應於替換變量後的模板字符串
String.rawHi\n${2+3}!;
//"Hi\n5!"3d

String.rawHi\\n
//"Hi\n"rest

String.raw = function(strings,...values){
    var output = "";
    for(var index = 0;index<values.length;index++){
        output += strings.raw[index]+values[index];
    }

    output += strings.raw[index];
    return output;
}

String.raw方法能夠做爲處理模板字符串的基本方法,它會將全部變量替換,並對反斜線進行轉義,方便下一步做爲字符串使用
String.raw方法也能夠做爲正常的函數使用,這時,其第一個參數應該是一個具備raw屬性的對象,且raw屬性的值應該是一個數組。code

String.raw({raw:'test'},0,1,2);
//"t0e1s2t"

//等同於
String.raw({raw:['t','e','s','t']},0,1,2);
相關文章
相關標籤/搜索