作者选择了COVID-19 救济基金来接受捐赠,作为Write for DOnations计划的一部分。
介绍
ECMAScript 规范 (ES6)的2015 版向 JavaScript 语言添加了模板文字。模板字面量是在 JavaScript中创建字符串的一种新形式,它添加了许多强大的新功能,例如更轻松地创建多行字符串以及使用占位符将表达式嵌入到字符串中。此外,称为标记模板文字的高级功能允许您对字符串中的表达式执行操作。所有这些功能都增加了作为开发人员的字符串操作选项,让您可以生成可用于URL或自定义HTML 元素的函数的动态字符串。
在本文中,您将回顾单/双引号字符串和模板文字之间的区别,通过各种方式来声明不同形状的字符串,包括多行字符串和根据变量值而变化的动态字符串或表达。然后,您将了解标记模板并查看使用它们的一些实际项目示例。
声明字符串
本节将回顾如何使用单引号和双引号声明字符串,然后将向您展示如何对模板文字执行相同的操作。
在 JavaScript 中,字符串可以用单引号 ( ' '
)编写:
const single = 'Every day is a good day when you paint.'
字符串也可以用双引号 ( " "
)编写:
const double = "Be so very light. Be a gentle whisper."
JavaScript 在单引号或双引号字符串之间没有重大区别,这与其他语言可能允许在一种类型的字符串中而不是另一种类型中进行插值不同。在这种情况下,插值是指将占位符评估为字符串的动态部分。
单引号或双引号字符串的使用主要取决于个人喜好和约定,但结合使用时,每种类型的字符串只需要转义其自己的引号类型:
// Escaping a single quote in a single-quoted string
const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'
// Escaping a double quote in a double-quoted string
const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"
console.log(single);
console.log(double);
该结果log()
这里方法将打印相同的两个字符串到控制台:
Output"We don't make mistakes. We just have happy accidents." - Bob Ross
"We don't make mistakes. We just have happy accidents." - Bob Ross
另一方面,模板文字是通过用反引号字符或重音符 ( `
)包围字符串来编写的:
const template = `Find freedom on this canvas.`
他们不需要转义单引号或双引号:
const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross`
但是,他们仍然需要转义反引号:
const template = `Template literals use the \` character.`
模板文字可以做普通字符串可以做的所有事情,因此您可以用它们替换项目中的所有字符串并具有相同的功能。但是,代码库中最常见的约定是仅在使用模板文字的附加功能时才使用模板文字,并且对所有其他简单字符串始终使用单引号或双引号。如果其他开发人员检查,遵循此标准将使您的代码更易于阅读。
现在您已经了解了如何使用单引号、双引号和反引号声明字符串,您可以继续了解模板文字的第一个优点:编写多行字符串。
多行字符串
在本节中,您将首先了解在 ES6 之前声明多行字符串的方式,然后了解模板文字如何使这变得更容易。
最初,如果您想在文本编辑器中编写一个跨越多行的字符串,您可以使用连接运算符。然而,这并不总是一个直接的过程。以下字符串连接似乎跨越多行:
const address =
'Homer J. Simpson' +
'742 Evergreen Terrace' +
'Springfield'
这可能允许您将字符串分解为更小的行并将其包含在文本编辑器中的多行中,但它对字符串的输出没有影响。在这种情况下,字符串都在一行上,而不是用换行符或空格分隔。如果您登录address
到控制台,您将获得以下信息:
OutputHomer J. Simpson742 Evergreen TerraceSpringfield
您可以使用反斜杠字符 ( \
) 将字符串延续到多行:
const address =
'Homer J. Simpson\
742 Evergreen Terrace\
Springfield'
这将保留任何缩进作为空格,但字符串仍将在输出中的一行上:
OutputHomer J. Simpson 742 Evergreen Terrace Springfield
使用换行符 ( \n
),您可以创建一个真正的多行字符串:
const address =
'Homer J. Simpson\n' +
'742 Evergreen Terrace\n' +
'Springfield'
登录到控制台后,将显示以下内容:
OutputHomer J. Simpson
742 Evergreen Terrace
Springfield
然而,使用换行符来指定多行字符串可能违反直觉。相比之下,使用模板文字创建多行字符串可以更直接。无需连接、使用换行符或使用反斜杠。ENTER
默认情况下,只需按下并跨多行写入字符串即可:
const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`
将此记录到控制台的输出与输入相同:
OutputHomer J. Simpson
742 Evergreen Terrace
Springfield
任何缩进都将被保留,因此重要的是不要在不需要的情况下缩进字符串中的任何其他行。例如,请考虑以下情况:
const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`
尽管这种编写行的风格可能会使代码更具可读性,但输出不会是:
OutputHomer J. Simpson
742 Evergreen Terrace
Springfield
现在介绍了多行字符串,下一节将讨论如何使用不同的字符串声明将表达式插入到它们的值中。
表达式插值
在 ES6 之前的字符串中,连接用于创建带有变量或表达式的动态字符串:
const method = 'concatenation'
const dynamicString = 'This string is using ' + method + '.'
当登录到控制台时,这将产生以下结果:
OutputThis string is using concatenation.
使用模板文字,表达式可以嵌入到占位符中。占位符由 表示${}
,大括号内的任何内容都视为 JavaScript,括号外的任何内容都视为字符串:
const method = 'interpolation'
const dynamicString = `This string is using ${method}.`
当dynamicString
登录到控制台时,控制台将显示以下内容:
OutputThis string is using interpolation.
在字符串中嵌入值的一个常见示例可能是用于创建动态 URL。使用串联,这可能很麻烦。例如,以下声明了一个生成OAuth访问字符串的函数:
function createOAuthString(host, clientId, scope) {
return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope
}
createOAuthString('https://github.com', 'abc123', 'repo,user')
记录此函数将生成以下 URL 到控制台:
Outputhttps://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user
使用字符串插值,您不再需要跟踪打开和关闭字符串以及连接运算符的位置。这是模板文字的相同示例:
function createOAuthString(host, clientId, scope) {
return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
}
createOAuthString('https://github.com', 'abc123', 'repo,user')
这将具有与串联示例相同的输出:
Outputhttps://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user
您还可以在模板文字上使用该trim()
方法来删除字符串开头或结尾的任何空格。例如,以下使用箭头函数创建带有自定义链接的 HTML<li>
元素:
const menuItem = (url, link) =>
`
<li>
<a href="${url}">${link}</a>
</li>
`.trim()
menuItem('https://google.com', 'Google')
结果将去除所有空白,确保元素正确呈现:
Output<li>
<a href="https://google.com">Google</a>
</li>
可以插入整个表达式,而不仅仅是变量,例如在这个两个数字之和的示例中:
const sum = (x, y) => x + y
const x = 5
const y = 100
const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`
console.log(string)
此代码定义sum
函数和变量x
and y
,然后在字符串中同时使用函数和变量。记录的结果将显示以下内容:
OutputThe sum of 5 and 100 is 105.
这对于允许在字符串中使用条件的三元运算符特别有用:
const age = 19
const message = `You can ${age < 21 ? 'not' : ''} view this page`
console.log(message)
此处记录的消息将根据 的值age
是 over 还是 under 发生变化21
。由于19
在此示例中,将记录以下输出:
OutputYou can not view this page
现在您已经了解模板文字在用于插入表达式时如何有用。下一节将更进一步,检查标记模板文字以处理传递给占位符的表达式。
标记模板文字
模板文字的一个高级特性是使用标记的模板文字,有时也称为模板标签。标记模板以解析模板文字的标记函数开头,允许您更好地控制操作和返回动态字符串。
在此示例中,您将创建一个tag
函数以用作对标记模板进行操作的函数。字符串文字是函数的第一个参数,在strings
此处命名,任何插入到字符串中的表达式都使用rest 参数打包到第二个参数中。您可以控制台输出参数以查看它们将包含的内容:
function tag(strings, ...expressions) {
console.log(strings)
console.log(expressions)
}
将该tag
函数用作标记模板函数,并按如下方式解析字符串:
const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`
由于您是控制台日志记录strings
和expressions
,这将是输出:
Output(4) ["This is a string with ", " and ", " and ", " interpolated inside."
(3) [true, false, 100]
第一个参数 ,strings
是一个包含所有字符串文字的数组:
"This is a string with "
" and "
" and "
" interpolated inside."
raw
这个参数还有一个可用的属性 at strings.raw
,它包含没有处理任何转义序列的字符串。例如,/n
将只是字符/n
而不是转义为换行符。
第二个参数 ,...expressions
是一个包含所有表达式的剩余参数数组:
true
false
100
字符串文字和表达式作为参数传递给标记模板函数tag
。注意带标签的模板不需要返回字符串;它可以对这些值进行操作并返回任何类型的值。例如,我们可以让函数忽略所有内容并返回null
,就像在这个returnsNull
函数中一样:
function returnsNull(strings, ...expressions) {
return null
}
const string = returnsNull`Does this work?`
console.log(string)
记录string
变量将返回:
Outputnull
可以在标记模板中执行的操作的一个示例是对每个表达式的两侧应用一些更改,例如如果您想将每个表达式包装在 HTML 标记中。创建一个bold
将<strong>
和添加</strong>
到每个表达式的函数:
function bold(strings, ...expressions) {
let finalString = ''
// Loop through all expressions
expressions.forEach((value, i) => {
finalString += `${strings[i]}<strong>${value}</strong>`
})
// Add the last string literal
finalString += strings[strings.length - 1]
return finalString
}
const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`
console.log(string)
此代码使用该forEach
方法循环expressions
数组并添加粗体元素:
OutputThis is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.
在流行的 JavaScript 库中有一些标记模板文字的例子。该graphql-tag
库使用gql
标记模板将GraphQL查询字符串解析为 GraphQL 理解的抽象语法树(AST):
import gql from 'graphql-tag'
// A query to retrieve the first and last name from user 5
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`
另一个使用标记模板函数的库是styled-components
,它允许您从常规DOM元素创建新的React 组件并将其他CSS 样式应用于它们:
import styled from 'styled-components'
const Button = styled.button`
color: magenta;
`
// <Button> can now be used as a custom component
您还可以String.raw
对标记的模板文字使用内置方法来防止处理任何转义序列:
const rawString = String.raw`I want to write /n without it being escaped.`
console.log(rawString)
这将记录以下内容:
OutputI want to write /n without it being escaped.
结论
在本文中,您回顾了单引号和双引号字符串文字,并了解了模板文字和标记模板文字。模板文字通过在字符串中插入表达式并创建多行字符串而无需任何连接或转义,使许多常见的字符串任务变得更简单。模板标签也是许多流行库使用的模板文字的有用高级功能,例如 GraphQL 和styled-components
.
要了解有关 JavaScript 中字符串的更多信息,请阅读如何在 JavaScript 中使用字符串和如何在 JavaScript 中索引、拆分和操作字符串。