toString() 和 String()
有两种方式把一个值转换为字符串。首先是使用几乎所有值都有的 toString()
方法。这个方法唯
一的用途就是返回当前值的字符串等价物。比如:
const name = '张三'
const age = 22
console.log(name.toString()) // 张三
console.log(age.toString()) // 22
toString()
方法可见于数值、布尔值、对象和字符串值。(没错,字符串值也有toString()
方法,该方法只是简单地返回自身的一个副本。)null
和undefined
值没有toString()
方法。
多数情况下,toString()
不接收任何参数。不过,在对数值调用这个方法时,toString()
可以接收一个底数参数,即以什么底数来输出数值的字符串表示。默认情况下,toString()
返回数值的十进制字符串表示。而通过传入参数,可以得到数值的二进制、八进制、十六进制,或者其他任何有效基数的字符串表示,比如:
const num = 10
// 默认以十进制表示
console.log(num.toString()) // 10
// 以二进制表示
console.log(num.toString(2)) // 1010
// 以八进制表示
console.log(num.toString(8)) // 12
// 以十进制表示
console.log(num.toString(10)) // 10
// 以十六进制表示
console.log(num.toString(16)) // a
// 以四进制表示
console.log(num.toString(4)) // 22
如果你不确定一个值是不是null
或undefined
,可以使用String()
转型函数,它始终会返回表示相应类型值的字符串。String()函数遵循如下规则:
- 如果值有
toString()
方法,则调用该方法(不传参数)并返回结果; - 如果值是
null
,返回"null"; - 如果值是
undefined
,返回"undefined";
console.log(String(10)) // 10
console.log(String(true)) // true
console.log(String(undefined)) // undefined
console.log(String(null)) // null
console.log(undefined.toString()) // TypeError: Cannot read property 'toString' of undefined
模板字面量
ECMAScript 6 新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量保留
换行字符,可以跨行定义字符串:
const htmlStr = `
<html>
<head>
<title>hello</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
`
console.log(htmlStr)
// <html>
// <head>
// <title>hello</title>
// </head>
// <body>
// <h1>Hello, World!</h1>
// </body>
// </html>
支持字符串插值
模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。技术上讲,模板字面量不是字符串,而是一种特殊的 JavaScript 句法表达式,只不过求值后得到的是字符串。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。字符串插值通过在${}
中使用一个JavaScript 表达式实现:
const id = '2017001'
const name = '张三'
// 以前打印指定格式字符串方式
console.log('学号:' + id + ',姓名:' + name) // 学号:2017001,姓名:张三
// 使用模板字符串的插值操作方式
console.log(`学号:${id},姓名:${name}`) // 学号:2017001,姓名:张三
在插值表达式中可以调用函数和方法,将表达式转换为字符串时会自动调用toString()
方法:
const person = {
name: '张三',
age: 22,
toString() {
return `我叫${this.name}, 今年${this.age}岁`
}
}
console.log(`[将表达式转换成字符串时,会默认调用 toString() 方法]:${person}`) // [将表达式转换成字符串时,会默认调用 toString() 方法]:我叫张三, 今年22岁
支持定义标签函数
模板字面量也支持定义标签函数(tag function),而通过标签函数可以自定义插值行为。标签函数会接收被插值记号分隔后的模板和对每个表达式求值的结果。
const [name, age] = ['张三', 22]
const res = tagFunc`姓名:${name},年龄:${age}`
console.log(res)
// 自定义处理模板字符串的标签函数
function tagFunc(splitStrs, ...insertVals) {
console.log(splitStrs.join('|'))
console.log(insertVals.join('|'))
return '这是模板字符串使用标签函数后的返回值'
}
// 打印结果如下:
// 姓名:|,年龄:|(注:此处末尾有一个空字符串)
// 张三|22
// 这是模板字符串使用标签函数后的返回值
原始字符串
使用模板字面量也可以直接获取原始的模板字面量内容(如换行符或 Unicode 字符),而不是被转换后的字符表示。为此,可以使用默认的String.raw
标签函数:
console.log(`u00A9`) // ©
console.log(String.raw`u00A9`) // u00A9