4. String
1. 通用知识
在计算机编程中,字符串通常是一个字符序列,可以是字面量,也可以是变量。后者可能会允许修改元素和改变长度,也可能是固定的(在创建之后)。
字符串是一种数据类型,通常被实现为 bytes/characters/code units 的数组,存储着元素序列,元素通常是字符且会使用某种字符编码。用“数组”实现是为了快速访问单个单元的字符和子字符串,也有个别编程语言是用链表来实现的(比如 Haskell)。

字符串通常由字符组成。可用于存储人类可读的数据,如句子、按字母顺序排列的数据列表。
根据使用的编程语言和其提供的具体数据类型,声明为字符串的变量在内存中的存储,可能是静态分配预留了最大长度,也可能是动态分配以确保元素的数量是可变的。
字符串是一种非常重要且有用的数据类型,几乎所有的编程语言都实现了它。在不同的编程语言里,字符串可能是原始类型,也可能是复合类型。当字符串以字面量的形式出现在源代码中的时候,被称为是字符串字面量或匿名字符串。
定长+变长、字符集+字符编码、原始+复合类型、字面量
2. String 类型
在 JavaScript 里,String 类型用来表示文本数据,它是一组 16 位无符号整数值的“元素”。
字符串里的每个元素都占了一个位置,我们可以通过下标来访问每个元素,下标从 0 开始。字符串的长度就是它里面元素的个数。如下:
let foo = 'JavaScript';
foo[0]; // "J"
foo[1]; // "a"
foo.length; // 103. String 对象
在 JavaScript 中,String 对象是 String 原始值的对象包装器,用来表示和操作字符序列。
3.1 构造器
new String()返回对象,搭配 new 关键字作为构造函数用String()返回字符串,直接当函数用可做类型转换(此方式更有用)
3.2 静态方法
String.fromCharCode()传 Unicode 值序列String.fromCodePoint()传代码点序列String.raw()传原始模板字符串
3.3 实例属性
String.prototype.length只读
3.4 实例方法
String.prototype.xxx
3.4.1 通用方法
valueOf()toString()
3.4.2 常用操作
下标→单个字符
at()charAt()charCodeAt()codePointAt()
字符串→下标
indexOf()lastIndexOf()
是否以指定字符串开始、结束、包含
startsWith()endsWith()includes()
提取子串,传起始下标
slice()substring()已不推荐使用substr()
正则表达式
search()match(),matchAll()replace(),replaceAll()
split()变数组concat()拼接大小写
toLowerCase()toUpperCase()toLocaleLowerCase()toLocaleUpperCase()
去首尾空格
trim()trimStart()trimEnd()
前后对齐
padEnd()padStart()
3.4.3 其它
normalize()返回 Unicode 正规形式repeat()传重复次数localeCompare()比较@@iterator()迭代器
4. 常见操作
4.1 创建字符串
创建字符串原始值,可以使用字符串字面量和函数。如下:
创建字符串对象,可以使用字符串对象的构造器。如下:
4.2 原始值和对象
在大多数情况下,字符串原始值和字符串对象是可以互换使用的。JavaScript 会自动把字符串原始值转成对象,以便在字符串原始值上使用字符串对象的方法。
但是,字符串原始值和字符串对象,还是有些区别的。
区别一:typeof 的结果不同
区别二:eval() 的结果不同
当然,可以通过手动调用 valueOf() 来“修复”。如下:
4.3 访问单个字符
方法一:使用 charAt()
方法二:使用 []。这是在 ES5 里引入的,它把字符串视为类数组(array-like)对象,然后单个字符对应一个数字索引。
当使用[]进行字符访问的时候,尝试删除或者重新赋值是不会生效的,因为所涉及的属性是不可写、不可配置的。
4.4 字符串比较
可以用运算符>和< 以及实例方法 localeCompare()。
这里需要注意的是,用==运算符比较的两个字符串是大小写敏感的。如果不想区分大小写,可以先都转成大写再用===。如下:
这里用了toUpperCase()而不是toLowerCase(),是考虑到某些 UTF-8 字符转换的问题。
4.5 类型转换
和 .toString()相比,String()更可靠,因为它还适用于 undefined, null 和 symbol。
5. 注意事项
5.1 长字符串字面量
方法一:使用操作符 +。如下:
方法二:在行尾加 \,以表示该字符串还会在下一行继续。如下:
注意:在\之后不能有空格、注释和其它任何字符(换行符除外),否则它就不工作了。
5.2 输出多行字符串
可使用模板字符串,它支持直接换行。
源代码里的任何字符(包括换行符)都是模板字面量的一部分,所以上面的字符串里是含有字符的。
5.3 慎用字符串模拟数组
在实际使用中,我们可能会用字符串来模拟数组/列表,但这么做是有潜在风险的。
要么分隔符可能就是列表里的元素本身,要么就得挑个特殊的字符来当分隔符。前者可能会导致列表不工作,后者不仅要约定特殊字符而且还会增加后续的维护成本。
所以,尽量用字符串表示文本数据。
5.4 字符集和编码方式
这个话题较为独立,详见《Unicode 字符编码模型》。
6. 主要参考
Last updated