在 ECMAScript2015 中增强了定义字符串的方式,ECMAScript2015 之前定义字符串需要通过单引号或者双引号的方式,如下代码所示:
const str = 'hello es2015, this is a string.'
console.log(str)
在 ECMAScript2015 中新增了一种叫做模板字符串的方式来定义字符串,它需要使用反引号(`)进行标识。如下代码所示:
const str = `hello es2015, this is a string.`
console.log(str)
直接使用模板字符串和之前传统方式是没有什么区别的。如果在字符串里面需要使用反引号,也可以通过 \
去转义。如下代码所示:
const str = `hello es2015, this is a \`string\`.`
console.log(str)
相比于普通的字符串,这种模板字符串多了很多有用的新特性。首先,传统字符串并不支持换行,如果字符串里面存在换行的话,需要通过 \n
这种方式来实现。如下代码所示:
const str = 'hello es2015, \nthis is a string.'
console.log(str)
上述代码的运行结果如下:
hello es2015,
this is a string.
而在模板字符串中是支持多行字符换的,也就是说,允许在模板字符串中直接输入换行符。如下代码所示:
const str = `hello es2015,
this is a \`string\`.`
console.log(str)
上述代码的运行结果如下:
hello es2015,
this is a `string`.
模板字符串的这一特点对于输出 HTML 格式的字符串是非常方便的。其次,模板字符串还支持通过插值表达式的方式在字符串当中嵌入对应的数值。如下代码所示:
const name = '前端课湛'
const msg = `Hey, ${name}`
console.log(msg)
上述代码的运行结果如下:
Hey, 前端课湛
从上述代码的运行结果可以看到,在模板字符串中通过插值表达式嵌入了 name 变量来获取该变量的值。如下图所示:
这种在模板字符串中使用插值表达式的方式比之前普通字符串的方式要方便的多,也更直观一点,不容易写错。实际上,花括号中的内容就是标准的 JavaScript。也就是说,这里不仅仅可以嵌入变量,还可以嵌入任何标准的 JavaScript 语句,这个语句的返回值最终会输出到模板字符串当中插值表达式所在的位置。如下代码所示:
const result = `${ 1 + 2} --- ${Math.random()}`
console.log(result)
上述代码的运行结果如下:
3 --- 0.7101392860529787
除了上述特性以外,模板字符串还有一个更高级的用法,就是在定义模板字符串之前去添加一个标签。这个标签实际上就是一个特殊的函数,添加这个标签就是调用这个函数。比如使用 console.log
作为模板字符串的标签,如下代码所示:
const str = console.log `hello world`
上述代码的运行结果如下:
[ 'hello world' ]
打印的结果为什么会是一个数组呢?想要知道这个答案,就得从标签函数入手来看它的运行方式。这里可以自定义一个标签函数,如下代码所示:
const name = 'lucy'
const gender = true
function myTagFunc(strings) {
console.log(strings)
}
const result = myTagFunc `hey, ${name} is a ${gender}`
这里自定义了一个名为 myTagFunc
的标签函数,这个函数可以接收一个数组参数,先将这个数组参与进行打印,结果如下:
[ 'hey, ', ' is a ', '' ]
打印的结果可以看到,实际上这个内容就是把模板字符串进行分割之后的结果。因为模板字符串可能存在插值表达式,而这个数组参数获取到的就是按照插值表达式进行分割之后的静态内容。
这个标签函数除了可以接收这个数组参数以外,还可以接收在这个模板字符串中所有插值表达式的返回值。如下代码所示:
const name = 'lucy'
const gender = true
function myTagFunc(strings, name, gender) {
console.log(strings, name, gender)
}
const result = myTagFunc `hey, ${name} is a ${gender}`
上述代码的运行结果如下:
[ 'hey, ', ' is a ', '' ] 'lucy' true
这个标签函数的返回值就是模板字符串所对应的返回值,如下代码所示:
const name = 'lucy'
const gender = true
function myTagFunc(strings, name, gender) {
return '123'
}
const result = myTagFunc `hey, ${name} is a ${gender}`
console.log(result)
所以如果这里需要返回正常的字符串内容的话,只需要通过数组参与和插值表达式的结果进行拼接即可。如下代码所示:
const name = 'lucy'
const gender = true
function myTagFunc(strings, name, gender) {
return strings[0] + name + strings[1] + gender + strings[2]
}
const result = myTagFunc `hey, ${name} is a ${gender}`
console.log(result)
上述代码的运行结果如下:
hey, lucy is a true
这种标签函数的作用实际上就是对模板字符串进行加工,比如上述代码中的 gender
就是直接输出 true
或者 false
,就可以在标签函数中对 gender
进行一些加工,这样的话可以让返回的结果更适合用户的阅读。如下代码所示:
const name = 'lucy'
const gender = true
function myTagFunc(strings, name, gender) {
const sex = gender ? 'man' : 'woman'
return strings[0] + name + strings[1] + sex + strings[2]
}
const result = myTagFunc `hey, ${name} is a ${gender}`
console.log(result)
上述代码的运行结果如下:
hey, lucy is a man
利用模板字符串中标签函数的这一个特性,来实现比如像文本的多语言化、检查模板字符串中是否存在不安全字符的一些需求,甚至可以利用这一特性来实现一个小型的模板引擎。
在 ECMAScript2015 当中为字符串提供了一些扩展的方法,这里主要介绍几个比较常用的方法:
includes()
方法startsWith()
方法endsWith()
方法上述方法是一组方法,可以用来更方便地判断某个字符串当中是否包含指定内容。如下代码所示:
const message = 'Error: foo is not defined.'
console.log(
// 判断指定字符串是否是以'Error'开头
message.startsWith('Error'),
// 判断指定字符串是否是以'.'结束
message.endsWith('.'),
// 判断指定字符串是否包含'foo'
message.includes('foo')
)
上述代码的运行结果如下:
true true true
相比之前使用 indexOf()
方法或者是正则表达式去判断,这样一组方法会让字符串的查找便捷很多。