前言
模板字符串(template string)是 ECMAScript 2015 规范中的一种新特性,在平常开发中使用频率非常高。也可称作模板字面量(template literal)。
正文
常规用法
模板字符串使用反引号(` `)来代替普通字符串中的用双引号和单引号。
// 单行字符串 `single line text` // 多行字符串 `multiline text 1 multiline text 2` // 嵌入表达式 function sayHi(name) { console.log(`Hi, ${name}~`) } // 模板字符串内使用反引号,需在前面添加转义符 (\) `\`` === '`' // true
需要注意的是,模板字符串内的「任意字符」都是它的一部分,包括很容易被视觉忽略的前导尾随空格、换行符等「空白符」。比如:
String.raw`multiline text 1 multiline text 2` // "multiline text 1\n multiline text 2"
以上 String.raw()
是模板字符串的标签函数(下面会介绍),它返回指定模板字符串的原始字符串,可以看到它是包含 \n
(换行符和空格)的。
它也支持嵌套语法,比如:
const className = `flex-center ${isShow ? `display ${isLarge ? 'big' : 'normal'}` : ''}`
以上这些内容,相信看到这篇文章的你都懂,没什么问题。
进阶用法
如果你在项目中使用过 CSS-in-JS,可以经常看到类似这样的语法:
import styled from 'styled-components' const Button = styled.button` color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `
以上是 styled-components 的基础用法。
这看起来有点“奇怪”的语法,正是模板字符串中的标签模板(tagged template)。看个例子:
alert`Hey`
以上等同于 alert('Hey')
,在这里 alert
被称作「标签函数」。
因此「标签模板」实际上只是函数调用的一种特殊形式。标签指的是函数(即 alert()
方法),而函数后面的模板字符串就是它的参数。
如果标签模板中的模板字符串是包含变量的,就不是简单的调用了。比如:
const name = 'Frankie' // 标签模板 tag`Hey, ${name}~` // 等同于这样调用函数 tag(['Hey, ', '~'], 'Frankie')
标签函数的第一个参数,是模板字符串中由不包含 ${expression}
部分的字符串拆分而成的数组。即 `Hey, ${name}~` 中的剔除掉 ${name}
后拆分组成的数组。而后面的参数则为模板字符串中的所有变量。注意,标签函数并不是只能返回字符串,它也是一个普通函数,可以返回任何值。
形式如:
function tagFunction(strArr, ...values) { // some statements... }
其中标签函数第一个参数中,存在一个特殊的属性 raw
,通过它可以访问模板字符串的「原始字符串」,而不经过特殊字符的转换。
function tagFunction(strArr) { console.log(strArr.raw[0]) } tagFunction`multiline text 1 multiline text 2` // "multiline text 1\n multiline text 2"
应用场景
- 写 GraphQL 应用常用的 graphql-tag 库,就是应用了标签函数的语法,写法很简洁。
import gql from 'graphql-tag'; const query = gql` { user(id: 5) { firstName lastName } } `
未完待续...