在 ES2015(也稱為 ES6)中引入的樣板文字提供了一種新的聲明字符串的方式,同時還提供了一些新的有趣的構造方法,並且已經被廣泛地使用。
樣板文字介紹
樣板文字是 ES2015 / ES6 中的一個新功能,與 ES5 及其以下版本相比,它以一種新穎的方式處理字符串。
從外觀上看,語法非常簡單,只需使用反引號(`)而不是單引號或雙引號即可:
const a_string = `something`
它們之所以獨一無二,是因為它們提供了很多普通字符串所不具備的功能,尤其是:
- 它們提供了一種很好的語法來定義多行字符串
- 它們提供了一種簡單的方式將變量和表達式插入字符串中
- 它們允許您使用樣板標籤創建特定領域的語言(DSL,即“domain specific language”),例如 React 中的 Styled Components 用於為組件定義 CSS
讓我們逐一詳細介紹這些功能。
多行字符串
在 ES6 之前,要創建跨兩行的字符串,您必須在行末使用反斜線字符(\
):
const string =
'first part \
second part'
這允許在兩行上創建字符串,但實際呈現在只有一行上:
first part second part
要將字符串呈現為多行,您需要在每行末尾明確添加 \n
,如下所示:
const string =
'first line\n \
second line'
或者
const string = 'first line\n' + 'second line'
樣板文字使多行字符串變得更簡單。
一旦使用反引號打開樣板文字,您只需按 Enter 鍵即可換行,不需要特殊字符,並且渲染的結果就是原樣:
const string = `Hey
this
string
is awesome!`
請記住,空格是有意義的,因此這樣做:
const string = `First
Second`
會產生以下字符串:
First
Second
解決這個問題的一種簡單方法是在第一行留空,然後在最後的反引號後面添加 trim() 方法,該方法將刪除第一個字符之前的任何空格:
const string = `
First
Second`.trim()
插值
樣板文字提供了一種簡單的方式將變量和表達式插入字符串中。
通過使用 ${...}
語法來實現插值:
const myVariable = 'test'
const string = `something ${myVariable}` //something test
在 ${}
中,您可以添加任何內容,甚至是表達式:
const string = `something ${1 + 2 + 3}`
const string2 = `something ${doSomething() ? 'x' : 'y'}`
樣板標籤
模板標籤(Tagged templates)是一種可能一開始對您來說看起來不是很有用的功能,但它實際上被許多廣泛使用的庫(如 Styled Components 或 Apollo - 一個用於定義 GraphQL 查詢模式的客/服務器庫)所使用,因此理解其工作原理是非常重要的。
在 Styled Components 中,模板標籤用於定義 CSS 字符串:
const Button = styled.button`
font-size: 1.5em;
background-color: black;
color: white;
`
在 Apollo 中,模板標籤用於定義 GraphQL 查詢模式:
const query = gql`
query {
...
}
`
上述示例中突出顯示的 styled.button
和 gql
模板標籤只是函數:
function gql(literals, ...expressions) {}
這個函數返回一個字符串,它可以是任意計算的結果。
literals
是一個包含由表達式插值化樣板文字內容的數組。
expressions
包含所有插值。
如果我們觀察上面的例子:
const string = `something ${1 + 2 + 3}`
在這種情況下,literals
是一個包含兩個項目的數組。第一個項目是 something
,從第一個插值(我們只有一個插值)之前的字符串開始,第二個項目是一個空字符串,即第一個插值結束(这里只有一个插值)和字符串結束之間的空格。
expressions
在這個例子中是一個包含一個元素 6
的數組。
更複雜的例子是:
const string = `something
another ${'x'}
new line ${1 + 2 + 3}
test`
在這種情況下,literals
是一個包含三個項目的數組。第一個項目是:
;`something
another `
第二個項目是:
;`
new line `
第三個項目是:
;`
test`
expressions
在這種情況下是一個包含兩個元素 x
和 6
的數組。
傳遞這些值的函數可以對其進行任何操作,這就是這種特性的強大之處。
最簡單的例子是模擬字符串插值,只需將 literals
和 expressions
結合起來:
const interpolated = interpolate`I paid ${10}€`
這就是 interpolate
函數的工作方式:
function interpolate(literals, ...expressions) {
let string = ``
for (const [i, val] of expressions.entries()) {
string += literals[i] + val
}
string += literals[literals.length - 1]
return string
}