# [Javascript] ES6 模板字串 (Template String) 知多少
# 小小的兩個 ` ` 學問可真不少
動態板模字串
Javasciript 在 ES6 後迎來了一大變革,不僅增加了許許多多的語法特性,在「字串」的撰寫上也增加了更多實用、方便的撰寫方法。
今天要來介紹的就是一個看似簡單,但卻功能強大的語法特性 — 模板字串 (Template String) 。
# 模板字串
有別於以前使用單引號 ‘’
或是雙引號 “”
將 文字 / 符號 / 數字 包住,所謂的模板字串就是使用 ```` 框住的一串 文字 / 符號 / 數字 。
# 字串拚接
傳統的字串拼接寫法,我們習慣使用 +
將多個字串、變數串接起來,以下為例:
var str = 'example line: ' + line1 + '\n' + 'column: ' + column;
模板字串的寫法,我們可以使用 ${變數名稱}
直接將變數安插在整個字串的自訂位置。並且,模板字串支援換行符號,我們不再需要使用 \n
表示換行。
var str = `example line: ${line1}
column: ${column}`;
以上這兩種的差異顯而易見。模板字串解決了傳統字串拼接的一大痛點 — 使用 +
進行拼接導致字串內容被拆分得過於零散,閱讀與維護得成本都相對較高。
模板字串允許變數直接插入字串之中,盡量保持字串預期呈現的格式,使得讀者在見到字串時便可一目了然,減少了閱讀時人腦轉換字串結果的「成本」。
以上,是模板字串最常使用的用法。大約涵蓋了 80% 以上的使用情境。
大部分人一般時間應該也就是使用到這樣的功能足矣。
然而,你知道板模字串的功能遠遠比上述更加強大嗎?
接下來要介紹的,就是板模字串更加強大的使用方法 — 板模標籤
# Tagged Template Literals
不知道各位有沒有使用過諸如 Styled Component、Apollo Graphql… 這幾類工具?
在 Styled Component 中,提供如下的寫法
https://styled-components.com/
https://www.apollographql.com/docs/tutorial/schema/
直接在模板字串之前使用函數,並且不需使用「括號 ( )」。
這是如何做到的?
這就是今天重點要說明的主題。
我們引用 MDN 上對於 Tagged Template Literals 的解釋。
標籤樣板字面值是一種更高級的樣板字面值形式,允許你透過 標籤函數 操作樣板字面值的輸出。
標籤函數的 第一個參數是一「字串陣列」 , 其餘參數則是「處理過的表達式」 。最終,你可以返回一個經處理後的字串,甚至是完全不一樣的東西。
標籤函數的名稱可以是任何你想要的。
什麼意思?
意思是,我們只要定義一個 function 符合第一個參數為 string array, 第二個參數為 rest argument,即可作為標籤函數。
我們使用以下幾個實驗來使我們了解這段話的意思。
定義一個 function 我們取名為 print
- 使用一個 純字串 看看
第一個參數將傳入的 string 變成了一個 array,而後面的 rest 沒有得到任何東西。
- 使用 帶有變數的 Template String 看看
這次,我們看到第一個參數接收的 array 為依照 ${}
的位置間格而成的字串;而第二個參數則是將 ${}
內的變數收集起來。
如此我們就知道,這個 function 的運作原理如下圖所示,清楚明瞭了。
因此,我們其實可以利用這特性,來做更加多樣的字串處理。
例如,我們便可以利用此特性,設計一個依照接收參數動態調整的字串板模
var dynamicTamplateString = props => (str_ary, ...rest_ary) => | |
str_ary.reduce( | |
(whole_str, cur_str, indx) => `${whole_str}${rest_ary[indx - 1](props)}${cur_str}` | |
); |
如此,我們便可以使用這個 helping function 寫一個自定義的模板。
const myTemplate = props => dynamicTamplateString(props)`I am a ${ | |
(props) => { | |
if (props.sex === 'M' && props.age > 20) return 'man'; | |
else if (props.sex === 'M' && props.age <= 20) return 'boy'; | |
else if (props.sex === 'W' && props.age > 20) return 'woman'; | |
else if (props.sex === 'W' && props.age <= 20) return 'girl'; | |
return 'Geek'; | |
} | |
}, I'm ${ | |
props => props.age | |
} years old, and I'm ${ | |
props => props.tall > 180 ? 'very tall' : 'not quite tall' | |
}`; |
如下表示。
# 結語
模板字串語法的使用情境很廣。了解這些特性,在未來程式開發中必定會大大提高效率。
# 參考資料
- JavaScript ES6 Template Literals 字串樣版
- MDN
- The magic behind 💅 styled-components