字符串的内部格式始终是 UTF-16,它不依赖于页面编码
赋值
单引号
let single = 'single-quoted'
双引号
let double = "double-quoted"
反引号(模板字符串)ES6
Unicode 字符
允许通过下述三种表示方式之一将一个字符以其十六进制 Unicode 编码的方式插入到字符串中:
\xXX
:XX
是介于00
到FF
之间的两位十六进制数,表示 Unicode 编码为XX
的字符\xXXXX
:XXXX
介于0000
到FFFF
之间,表示 Unicode 编码为XXXX
的字符\u{X~XXXXXX}
:介于0
和10FFFF
之间的 1 到 6 位十六进制值
\x
开头的后面要么是 2 位要么是 4 位,\u
开头的括号里可以是动态位数。
访问
- 方括号:
str[n]
- 方法:
str.charAt(n)
- 字符串长度:
str.length
操作
使用 +
可以连接字符串:'hello' + 'world'
当数值和字符串相加时,将得到字符串。JavaScript 从左向右计算表达式,不同的次序会产生不同的结果:
Warning
其他语言中有字符相减得 ascii 码差值的运算,但是 JS 相减会变成 number 再运算。所以需要使用
charCodeAt()
或codePointAt()
进行计算
编码
JS 采用 UTF-16 编码,只允许每个字符占 2 个字节长度,但 2 个字节只有 2^16 = 65536 种组合,不够表示所有的 Unicode 字符。
所以超过 2 个字节(U+FFFF)的稀有字符使用一对 两字节(代理对)来表示。所以造成常用字符是 2 字节 16 位,稀有字符是 4 字节 32 位。(代理对也就是 UTF-16 扩展字符)
- Unicode 编码:每个字符由 1-4 个字节的字节序列表示,U+0000~U+10FFFF
- UTF-16 编码:利用 Unicode 保留区域 D800~DBFF(作为高 16 位)和 DC00~DFFF(作为低 16 位)来对 U+10000~U+10FFFF 进行编码(读取到一个字符的编码在
\uD800...\uDBFF
这个范围中就表示它是一个代理对的前半部分,下个字符就必须在\uDC00...\uDFFF
)
有问题的用法
JS 中关于字符串的很多功能会有问题:
- length 是根据两个字节表示一个字符计算,所以可能 length 返回值与真实字符数量不一样
- slice 方法取不到预期的字符串
- for 循环遍历乱码
- …
没有问题的用法
关于迭代的用法是没问题的:
- for…of:
- 扩展运算符:
- Array.from:
Warning
新增的
codePointAt()
方法虽然能读取正确的代码对,但是依然是按照一个字节一个字节读取的,并不会跳过代理对的下半部分:
常用方法
查找字符
charAt ( index )
:返回指定位置的单个 UTF-16 码元(固定 2 字节)的 字符,超出范围返回 空字符串at ( index )
:返回指定位置的单个 UTF-16 码元(固定 2 字节)的 字符,支持负索引,超出范围返回 undefined
查字符的编码
charCodeAt ( index )
:返回指定位置字符的 UTF-16 代码单元(固定 2字节),超出范围返回 NaNcodePointAt ( index )
:能正确返回字符的完整 Unicode 编码(2字节 或 4字节),超出范围返回 undefined
查找位置
indexOf ( str[, start] )
:查找某个字符串第一次出现的索引,没找到返回 -1
str:要查找的字符串,默认为 ‘undefined’
start:开始查找的位置,默认为 0,小于 0 也等价于 0
lastIndexOf ( str[, start] )
:查找最后一次出现的索引,其他同上
判断开头、结尾、包含
startsWith ( searchStr[, start] )
:判断是否以某字符串开头,是返回 true,否返回 false
start:开始查找的索引,默认为 0
endsWith ( searchStr[, length] )
:判断是否以某字符串结尾,是返回 true,否返回 false
length:查找的长度,为 n 就是前 n 个字符里判断
includes ( searchStr[, start] )
:判断是否包含一个字符串,包含返回 true,不包含 false
start:开始查找的索引,默认为 0
检索、替换(正则)
match ( RegExp )
:检索字符串匹配到正则表达式的结果search ( RegExp )
:返回正则表达式首次匹配到的索引,否则返回 -1replace ( str/RegExp, newStr/func )
:查找 str 并替换成 newStr,返回新字符串
str / RegExp:
- 可以是字符串(只替换第一个)
- 可以是正则表达式
newStr / func:
- 可以是字符串
- 可以是函数,函数返回值替换掉前面的参数匹配到的结果
split ( [separator], [limit] )
:以字符串中的指定字符串为分隔符分割,返回拆分后的数组
separator:分隔字符串或正则,如果省略则返回的是一个当前字符串为一个元素的数组,如果是
''
则返回每个字符组成的数组
limit:整数,限定返回的拼接的数量
子串
slice ( start[, end] )
:提取[start, end)
的子串,返回新字符串
包括 start,不包括 end
start 默认 0,end 默认 length。可以为负数,表示倒数第几个
substring ( start[, end] )
:提取[start, end)
的子串,返回新字符串
包括 start,不包括 end
参数如果为 负数 或 NaN,则为 0,start > end 则执行结果跟它们互换一样
操作
trim ( )
:删除两端的空白字符,返回新字符串trimStart ( )
:删除开头的空白字符,返回新字符串trimEnd ( )
:删除结尾的空白字符,返回新字符串concat ( str2, str3 ... )
:拼接一个或多个字符串,返回新字符串(可以使用+
操作符代替)toUpperCase ( )
:返回大写形式的新字符串toLowerCase ( )
:返回小写形式的新字符串padStart ( targetLength[, padString] )
:用指定字符串从开头填充到目标长度padEnd ( targetLength[, padString] )
:用指定字符串从结尾填充到目标长度