这篇文章继续分享高程4第三章的内容。
3.4.6 String 类型
String (字符串)数据类型表示零或多个16位Unicode字符序列。字符串可以使用双引号(")、单引号(')或反引号(`)标示
跟某些语言中使用不同的引号会改变对字符串的解释方式不同,ECMAScript语法中表示字符串的引号没有区别。不过要注意的是,以某种引号作为字符串开头,必须仍然以该种引号作为字符串结尾。
1. 字符字面量
字符串数据类型包含一些字符字面量,用于表示非打印字符或有其他用途的字符
字面量 含义 \n 换行 \t 制表 \b 退格 \r 回车 \f 换页 \\\\ 反斜杠( \ ) \' 单引号( ' ),在字符串以单引号标示时使用,例如 'He said, \'hey.\''
\" 双引号( " ),在字符串以双引号标示时使
用,例如 "He said, \"hey.\""\\\` 反引号( \` ),在字符串以反引号标示时
使用,例如 \`He said,
\\\`hey.\\\`\`\xnn 以十六进制编码 nn 表示的字符(其中 n 是
十六进制数字0~F),例如 \x41 等于 "A"\unnnn 以十六进制编码 nnnn 表示的Unicode字符
(其中 n 是十六进制数字0~F),例如
\u03a3 等于希腊字符 "
这些字符字面量可以出现在字符串中的任意位置,且可以作为单个字符被解释(一个这样的字符字面量,之后让字符串的length加1,length并没有看起来的那么长)
注意 如果字符串中包含双字节字符,那么 length 属性返回的值可能不是准确的字符数。
2. 字符串的特点
ECMAScript中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量。(我的理解是:假设一个变量的值是一个字符串,我们当然可以给它赋值为另一个字符串,让它的值改变。但并不是“原来的字符串改成了现在的模样”,而是“按代码的意愿创建了新的字符串,把旧的字符串销毁了”)
3. 转换为字符串
有两种方式把一个值转换为字符串。
首先是使用几乎所有值都有的 toString() 方法。这个方法唯一的用途就是返回当前值的字符串等价物。
toString() 方法可见于数值、布尔值、对象和字符串值。(没错,字符串值也有 toString() 方法,该方法只是简单地返回自身的一个副本。) null 和 undefined 值没有toString() 方法。
多数情况下, toString() 不接收任何参数。不过,在对数值调用这个方法时, toString() 可以接收一个底数参数,即以什么底数来输出数值的字符串表示。默认情况下,toString() 返回数值的十进制字符串表示,想转成其他类型,就要传入底数。
另一个是String方法。转换的是先调用参数的toString方法,如果是null或者undefined,则会直接返回对应的字面量文本。
String() 函数遵循如下规则——
如果值有 toString() 方法,则调用该方法(不传参数)
并返回结果。
如果值是 null ,返回 "null" 。
如果值是 undefined ,返回 "undefined" 。
let value1 = 10;
let value2 = true;
let value3 = null;
let value4;
console.log(String(value1)); // "10"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
(另外,用加号操作符给一个值加上一个空字符串 "" 也可以将其转换为字符串,这是“隐式类型转换”的方法)
4. 模板字面量
ECMAScript 6新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量使用的是反引号,保留换行字符,可以跨行定义字符串。
顾名思义,模板字面量在定义模板时特别有用,比如下面这个HTML模板:(因为它可以跨行,这样正好可以保留HTML的缩进)
let pageHTML =
<div>
<a href="#">
<span>Jake</span>
</a>
</div>`;
由于模板字面量会保持反引号内部的空格,因此在使用时要格外注意,比如下面这里例子,你以为看不见的,其实也在字符串中占了位置——
// 这个模板字面量在换行符之后有25个空格符
let myTemplateLiteral = `first line
second line`;
console.log(myTemplateLiteral.length); // 47
// 这个模板字面量以一个换行符开头
let secondTemplateLiteral = `
first line
second line`;
console.log(secondTemplateLiteral[0] === '\n'); // true
// 这个模板字面量没有意料之外的字符
let thirdTemplateLiteral = `first line
second line`;
console.log(thirdTemplateLiteral[0]);
// f