ES6 章節:Template Literial
把過去的 “字串與變數” 做串接或是在 “變數和表達式” 做串接時,都必須使用「加號」做連結。
當文字比較多或是需要換行時就難以閱讀、且花很多時間整理,「樣板字面值」就是用來解決這樣的問題。
樣板字面值(Template literals)基本介紹
- 把過去的 “字串與變數” 做串接或是在 “變數和表達式” 做串接時,都必須使用「加號」做連結。
- 當文字比較多或是需要換行時就難以閱讀、且花很多時間整理,「樣板字面值」就是用來解決這樣的問題。
「傳統字串串接」寫法
const cash = 10;
const string = '氣氣氣氣';
const sentence = '我的 ' + cash + ' 元掉到水溝裡了,真是' + string;
console.log(sentence); // 我的 10 元掉到水溝裡了,真是氣氣氣氣
使用「樣板字面值」作替代 : 閱讀字串好理解
步驟一 : 文字內容外圍使用「反引號」(ㄅ左邊那個按鍵)把字串頭尾包起來
步驟二 : 使用 $ { 「變數」 或 「表達式內容」 }
試著在 $ { } 內插入「變數」
const cash = 10;
const string = '氣氣氣氣';
const sentence = `我的 ${ cash } 元掉到水溝裡了,真是${ string }`;
console.log(sentence); // 我的 10 元掉到水溝裡了,真是氣氣氣氣
試著在 $ { } 內插入「表達式」
使用 || 來設定「預設值」: 當 “前面的值” 為 “假值 falsy” 時,則使用「預設值」。
string || ‘好生氣啊’ 是一個「表達式」內容,一定會回傳一個值來供「樣板字面值」使用。
const cash = 10;
const string = '';
const sentence = `我的 ${cash} 元掉到水溝裡了,真是${string||'好生氣啊'}`;
console.log(sentence); //我的 10 元掉到水溝裡了,真是好生氣啊
✏️ 範例 — 使用「樣板字面值」組成 HTML 程式碼結構
希望能使用物件資料組成如以下的 HTML 程式碼結構。
<div id="list">
<!-- 希望組成以下結構
<ul>
<li>我是 XXX,身上有多少元</li>
<li>我是 XXX,身上有多少元</li>
<li>我是 XXX,身上有多少元</li>
</ul> -->
</div>
要把以下的物件資料一一陳列在 HTML 頁面上。
const people = [
{
name: '小明',
cash: 50
},
{
name: '阿姨',
cash: 5000
},
{
name: '杰倫',
cash: 10000
}
];
先來看看使用「傳統字串串接」寫法來做多行的撰寫有多麻煩~
- 在 “換行” 的地方要加上「反斜線 \」,否則無法輸出。
- 當變數很多,程式碼顯得凌亂。
- 「傳統字串串接」使用「加號 +」和「單引號 ’ ‘」來串接物件的變數內容。
const listString = '<ul> \
<li>我是 '+ people[0].name +',身上有多少 '+ people[0].cash +' 元</li> \
<li>我是 '+ people[1].name +',身上有多少 '+ people[1].cash +'元</li> \
<li>我是 '+ people[2].name +',身上有多少 '+ people[2].cash +'元</li> \
</ul>';
console.log(listString); // (如下圖)
將此段「傳統字串串接」組好的字串呈現在 HTML 頁面上。
document.querySelector('#list').innerHTML = listString;
使用「樣板字面值」更好閱讀
- 字串頭尾使用「反引號」包起來。
- 把 HTML 結構貼上,存檔後就可運作,字串即輸出。 (不需再加上「換行符號 \」)
- 將變數插入 $ { } 中。
const listString = `<ul>
<li>我是 ${ people[0].name },身上有 ${ people[0].cash } 元</li>
<li>我是 ${ people[1].name },身上有多少 ${ people[1].name } 元</li>
<li>我是 ${ people[2].name },身上有多少${ people[2].name } 元</li>
</ul>`;
console.log(listString); // (如下圖)
document.querySelector('#list').innerHTML = listString;
巢狀結構
前面介紹有提到樣板字面值(Template literals)是允許嵌入運算式 (即表達式) 的。
來看以下範例~
其中因為 person 物件下沒有屬性 cash,所以呈現 undefined 。
const person = {
name: '小明',
}
const sentence = `我是 ${ person.name },身上有帶 ${ person.cash } 元`;
console.log(sentence); // 我是 小明,身上有帶 undefined 元
因為 person 物件下沒有屬性 cash,可以使用 || 把屬性先填上「預設值」。person.cash || 1000
即為一段表達式 (會回傳一個值)。
const sentence = `我是 ${ person.name },身上有帶 ${ person.cash || 1000} 元`;
console.log(sentence); // 我是 小明,身上有帶 1000 元
person.cash = 1000
也是表達式內容。
表示將數字 1000 賦予至 person.cash 時,「等號 = 」會回傳一個值。
這裡的 1000 並不是 person.cash 的值,是使用「等號 = 」賦予到 person.cash 所回傳的值。
const sentence = `我是 ${ person.name },身上有帶 ${ person.cash = 1000} 元`;
console.log(sentence); // 我是 小明,身上有帶 1000 元
console.log(person.cash); // 1000 (查詢 person.cash 也會帶上1000的數值)
「樣板字面值」不能插入陳述式,會跳錯 (SyntaxError)
使用 const 宣告的方式屬於「陳述式」,不能這樣寫,結構有誤。
宣告變數屬於「陳述式」
const person = {
name: '小明',
}
const sentence = `我是 ${ person.name },身上有帶 ${ const a = 0 } 元`;
console.log(sentence); // SyntaxError: Unexpected token 'const'
函式本身的呼叫也屬於「表達式」
- 可以插入已經 “定義好” 的函式
- 可以插入一段「立即函式」
假設要插入的「立即函式」如下
(function(c){
return c * 2;
})(person.cash);
把「立即函式」帶入「面板字面值」
回傳 NaN 是因為 person 物件下並沒有定義 cash。
const person = {
name: '小明',
}
const sentence = `我是 ${ person.name },身上有帶 ${ (function(c){ return c * 2 })(person.cash) } 元`;
console.log(sentence); // 我是 小明,身上有帶 NaN 元
在 person 物件下定義 cash 屬性值。
const person = {
name: '小明',
cash: 1000
}
const sentence = `我是 ${ person.name },身上有帶 ${ (function(c){ return c * 2 })(person.cash) } 元`;
console.log(sentence); // 我是 小明,身上有帶 2000 元
把上段程式碼改成「箭頭函式」。
const person = {
name: '小明',
cash: 1000
}
const sentence = `我是 ${ person.name },身上有帶 ${ ((c) => c * 2 )(person.cash) } 元`;
console.log(sentence); // 我是 小明,身上有帶 2000 元
(巢狀手法)「面板字面值」內再插入一組「面板字面值」,一樣可以再插入「表達式」內容
const person = {
name: '小明',
cash: 1000
}
const sentence = `我是 ${ person.name }, ${ `身上有帶 ${ person.cash } ` } 元`;
console.log(sentence); // 我是 小明, 身上有帶 1000 元
✏️ 使用「迴圈」的方式把陣列值帶出
將陣列裡面的值,搭配 array.map 陣列方法、及「巢狀的樣板字面值」快速組成一個全新的 HTML 結構。
<div id="list"></div> // HTML 部分
JS 部分
const people = [ // 陣列資料
{
name: '小明',
cash: 50
},
{
name: '阿姨',
cash: 5000
},
{
name: '杰倫',
cash: 10000
}
];
搭配 array.map 方法 : 把陣列的值一一陳列出來,經過運算後,回傳成一個全新的陣列。
const listString = `<ul>
${ people.map((person) => `<li>我是 XXX,身上有多少元</li>`)}
</ul>`;
console.log(listString);
把物件資料變數帶進去,程式碼修改如下
const listString = `<ul>
${ people.map((person) => `<li>我是 ${person.name},身上有 ${person.cash } 元</li>`)}
</ul>`;
console.log(listString); // (如下圖)
document.querySelector('#list').innerHTML = listString;
會發現,li 結構之間多了「逗號」~
原因是因為 array.map 方法回傳的是一個陣列內容,我們需要把此陣列轉為「純字串」並把中間的「逗號」清除。
使用 join (’’) 方法 (中間插入空字串),把中間的「逗號」清除。
const listString = `<ul>
${ people.map((person) => `<li>我是 ${person.name},身上有 ${person.cash } 元</li>`).join('')}
</ul>`;
console.log(listString); // (如下圖)
document.querySelector('#list').innerHTML = listString;