字符串拼接方法
我們都知道,在ES5中字符串拼接方法比較繁瑣。同一條字符串不能換行且要頻繁用+拼接字符串。以拼接幾個
ES5字符串拼接:
for(var i = 0 ; i < 100 ; i ++){
html += '<li class="box">'
+'<span>hello</span>'
+'<strong>world</strong>'
+'<i>' + Math.random() +'</i>'
+'</li>'
}
可以看出字符串拼接頻繁用’'和+,導致代碼可讀性較差
ES6字符串拼接:
for(var i = 0 ; i < 100 ; i ++){
html += `<li class="box">
<span>hello</span>
<strong>world</strong>
<i> ${ Math.random() } </i>
</li>`
}
ES6取消了如此麻煩的字符串拼接方法,統一用反引號(``)包裹字符串,中間插入變量時統一用${要插入的變量}。極大的簡化了代碼,增強可讀性。
實現簡單的字符串模板渲染
介紹了ES6新增的字符串拼接方法,我們用這個方法實現一下簡單的字符串模板渲染。在實際頁面開發中,不可能拼接一次字符串就拼接一次字符串。而是會有一個模板,只需要按照模板寫好字符串就可以直接實現字符串的拼接插入;
1. 因爲模板裏面肯定包含js,所以我們對js代碼進行特殊標記; <% js代碼都放在這裏 %>
2. html結構在我們眼裏就是字符串; html沒有任何包裹;
3. 輸出的變量, 對變量進行一個特殊標記; <%= 變量都放在這裏 %>
代碼如下:
<script type="text/html" id="template">
<ul>
<% for(var i = 0 ; i < 10 ; i ++){ %>
<li> <strong> <%= i %></strong> <i> <%= i + 1 %> </i>
<button>這是個按鈕</button></li>
<% } %>
</ul>
</script>
這裏注意這個包含模板字符串的script標籤type類型爲text/html。表明這是一個html結構。
模板寫好了,那麼我們便需要處理一下這個模板字符串。我們的目標是將它處理成一個符合規範的js代碼。
處理目標:
print( `<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print(`<li>`);
print(i);
print(`</li>`)
}
print( `</ul>` );
注:print()是我們自定義的用來處理字符串函數,這裏以拼接字符串的功能舉例
正則方法替換特殊標記:
1.將開頭結尾的特殊標識處理掉
正則和字符串處理API——replace
template_str = template_str.replace(/<%[^=](.*?)%>/g ,`\`); \n $1 \n print(\`` );
處理結果:
<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print( `<li>`) <%= i %> print( `</li>`)
}
print( `</ul>
2.將處理後的字符串處理爲目標字符串
處理代碼:
template_str = template_str.replace(/<%=(.*?)%>/g ,`\`); \n print($1) \n print(\`` );
處理結果:
<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print( `<li> `) print(i) print( `</li>`)
}
print( `</ul>
3.繼續處理模板
處理代碼:
template_str = `print(\`${ template_str }\`)`;
處理結果:
print( `<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print( `<li> `) print(i) print( `</li>`)
}
print( `</ul>` );
4.將處理後的字符串加入函數體內,爲了方便字符串加入,函數也用字符串寫
var fn_str = `(function( data ){
var html = "";
function print(str){
html += str
}
${template_str} // 這是剛纔解析好的模板;
return html;
})`;
5.將這個含有函數的字符串處理爲一個真正的函數:
eval:將json格式的字符串處理爲js代碼
字符串內function需要加括號,需要加括號防止eval轉換成匿名函數後報錯
var temp_fn = eval( fn_str );
此時temp_fn便是處理好的函數。
完整代碼:
完整的處理字符串的代碼如下:
function renderTemplate( template_str , data ){
//date爲增強函數功能,可以傳入參數。這個例子中可以不需要
template_str = template_str.replace(/<%[^=](.*?)%>/g ,`\`); \n $1 \n print(\`` );
template_str = template_str.replace(/<%=(.*?)%>/g ,`\`); \n print($1) \n print(\`` );
//最後一步處理;
template_str = `print(\`${ template_str }\`)`;
var fn_str = `(function( data ){
var html = "";
function print(str){
html += str
}
${template_str} // 這是剛纔解析好的模板;
return html;
})`;
// 把這個字符串變成一個真正的函數;
var temp_fn = eval( fn_str );
var res = temp_fn( data );
return res;
}
// 獲取模板字符串
var template_str = document.getElementById("template").innerHTML
// 調用函數處理字符串
var html = renderTemplate( template_str )
// 將字符串插入list內
document.getElementById("list").innerHTML = html;