重讀《深入理解ES6》—— 模板字串

李等等扣丁發表於2019-03-04

ES6 引入了一種新型的字串字面量語法,我們稱之為模板字串(Template literals)。模板字串最大的優點是幫助我們解決了大量拼接字串的困擾。除此之外,模板字串還有一些其他的小細節,我們依次展開來說。

一、基本用法

模板字串的用法很簡單,它用反撇號(`)代替了 單引號 '' 或者 雙引號 ""

let msg = `a string`;
console.log(msg); // "a string"
console.log(typeof msg); // "string"
複製程式碼

二、多行字串

在 ES6 之前,如果我們想建立一個多行字串,必須使用 \n

// before ES6
var multiLine = "Hello \nWorld!";
console.log(multiLine); // "Hello 
                        // World!"
複製程式碼

而在 ES6 中,我們可以直接在程式碼換行即可。

// ES6
let multiLine = `Hello
World!`;

console.log(multiLine); // "Hello 
                        // World!"
複製程式碼

但有一點值得注意:在模板字串中,所有的留白都屬於字串的一部分! 也就是說,如果你的程式碼是下面這樣的話,那麼列印結果會保留空白。所以,在使用模板字串的過程中,一定注意空格和縮排。

let multiLine = `Hello
                 World!`;

console.log(multiLine); // "Hello 
                        // 			World!"
複製程式碼

三、字串佔位符

模板字串與普通字串最大的區別莫過於此。在模板字串中,我們可以把任意合法的 JS 表示式嵌入到佔位符中。由於這個強大的功能,大量拼接字串的操作將成為歷史。它看起來是這樣的 ${express}

在 ES6 之前,我們可能會這樣拼接字串:

// before ES6
var name = 'zhangsan';
var age = 19;
var info = "我的名字叫" + name + ", 我今年" + age + "歲。";
console.log(info);
複製程式碼

當有了模板字串,上面的程式碼可以簡化為:

let name = 'zhangsan';
let age = 19;
let info = `我的名字叫${name}, 我今年${age}歲。`;
console.log(info);
複製程式碼

除此之外,我們也可以放入一些較為複雜的表示式:

let count = 10;
let price = 2.5;
let total = `The total price is ${count * price}.`;
console.log(total); // The total price is 25.;
複製程式碼

四、標籤模板

標籤模板的基本用法是這樣的:tag`test` 。其中 tag 是一個我們自己定義的函式,而模板字串緊跟在後面。此時,該函式會被呼叫,用來處理這個模板字串。

function tag(stringArr) {
    console.log(stringArr);
}
tag`test`;
複製程式碼

重讀《深入理解ES6》—— 模板字串

標籤模板其實就是一種特殊的函式呼叫形式,“標籤”就是我們自己定義的函式,而“模板字串”就是它的引數。上面的例子中,函式返回一個字串陣列。

而如果模板字串中有佔位符(也就是變數),會將模板字串先處理成多個引數,再呼叫函式。

function tag(stringArr, value) {
    console.log(stringArr, value);
}

let a = 'aaa';
tag`test ${a}`;
複製程式碼

重讀《深入理解ES6》—— 模板字串

上面的程式碼中,stringArr 依然是一個字串陣列,它包含了兩部分:

  • 佔位符前的字串("test ");
  • 佔位符後的字串("");

value 就是佔位符 a 的值,傳參為 'aaa'

我們再稍微複雜一點:

function tag(stringArr, value, value2) {
    console.log(stringArr, value, value2);
}

let a = 'aaa';
let b = 3;
let c = 4;
tag`test ${a} next ${b * c}`;
複製程式碼

重讀《深入理解ES6》—— 模板字串

當我們有兩個佔位的時候,stringArr 就會有3個引數:

  • 第一個佔位符前面的字串("test ");
  • 第一個佔位符後面,第二個佔位符前面的字串(" next ");
  • 第二個佔位符後面的字串("");

value 是第一個佔位符的值,value2 是第二個佔位符的值。

理解了上面的例子,我們來總結一下:

function tag(stringArr, value, value2) {
    // ...
}
// 相當於
function tag(stringArr, ...value) {
   // ...
}

let a = 'aaa';
let b = 3;
let c = 4;
tag`test ${a} next ${b * c}`;
// 相當於
tag(["test ", " next ", ""], 'aaa', 12);
複製程式碼

tag 函式第一個引數是個陣列,該陣列的成員是模板字串中那些沒有佔位符替換的部分。如果模板字串中沒有佔位符,那麼該陣列中只有一個值;如果模板字串中有一個佔位符,那麼該陣列中有兩個值,分別是佔位符前面的字串和佔位符後面的字串;如果模板字串中有兩個佔位符,那麼該陣列中有三個值,分別是第一個佔位符前的字串、第一個佔位符和第二個佔位符之間的字串、第二個佔位符之後的字串。以此類推。

tag 函式的其他引數,就是模板字串中各個佔位符被替換後的值。

這就意味著 stringArr.length - 1 === value.length 的結果總是為 true 。通過這種模式,我們可以將 stringArrvalue 這兩個陣列交織在一起,重組結果字串。

function tag(stringArr, ...value) {
	let result = '';

	for (let i = 0; i < value.length; i++) {
		result += stringArr[i];
		result += value[i];
	}

	result += stringArr[literals.length - 1];

	return result;
}
複製程式碼

標籤模板的這種功能是非常強大的,當變數很多,或是資料需要一些處理,又或是要做出某種判斷的時候,我們完全可以在 tag 函式中來處理,最終得到想要的結果。

五、HTML 模板

利用佔位符和多行字串,我們可以非常輕易地在 JavaScript 程式碼中使用 HTML 模板。

假設我們通過請求獲得了以下的 JSON 資料:

// data
{
    "goodsId": 1,
    "price": 125,
    "goodsName": "斜挎包",
    "brand": "Dior",
    ...
}
複製程式碼

此時我們利用模板字串來建立一個 HTML 模板。

function createHtml(data) {
    return `
    	<p>The ${data.brand}/${data.goodsName} sells $${data.price}.</p>
    `
}
複製程式碼

如果文章中錯誤或表述不嚴謹的地方,歡迎指正

也歡迎大家關注我的同名微信公眾號:李等等扣丁

重讀《深入理解ES6》—— 模板字串

相關文章