本文内容主要来自《JavaScript高级程序设计(第4版)》章节5.3.3,并结合MDN文档中的 String 部分进行整理所得。
读取字符串内容
valueOf()、toString()、toLocaleString()
3 个继承的方法 valueOf()、toLocaleString() 和 toString() 都返回对象的原始字符串值。
JavaScript 字符
JavaScript 字符串由 16 位码元(code unit) 组成。对多数字符来说,每 16 位码元对应一个字符。
想要简单了解码元、码点可以看下 这篇文章。
charCodeAt() 和 String.fromCharCode()
charCodeAt() 方法可以查看指定码元的字符编码。
fromCharCode() 方法用于根据给定的 UTF-16 码元创建字符串中的字符。
对于 U+0000~U+FFFF 范围内的字符,length、charAt()、charCodeAt()和 fromCharCode() 返回的结果都跟预期是一样的。这是因为在这个范围内,每个字符都是用 16 位表示的,而这几个方法也都基于 16 位码元完成操作。
这个对应关系在扩展到 Unicode 增补字符平面时就不成立了。问题很简单,即 16 位只能唯一表示 65 536 个字符。这对于大多数语言字符集是足够了,在 Unicode 中称为基本多语言平面(BMP,Basic Multilingual Plane)。为了表示更多的字符,Unicode 采用了一个策略,即每个字符使用另外 16 位去选择一个增补平面。这种每个字符使用两个 16 位码元的策略称为代理对。
浏览器可以正确解析代理对(由两个码元构成), 并正确地将其识别为一个字符。
例如:
console.log('😁'.length); // 2
这时如果想要获取到表示 '😁' 这个字符的完整标识,我们需要使用到 codePointAt() 这个方法。
codePointAt() 和 String.fromCodePoint()
codePointAt() 接收 16 位码元的索引并返回该索引位置上的码点(code point)。码点是 Unicode 中一个字符的完整标识。
码点可能是 16 位,也可能是 32 位,而 codePointAt()方法可以从指定码元位置识别完整的码点。
fromCodePoint() 方法接收任意数量的码点,返回对应字符拼接起来的字符串.
at() 和 charAt()
at() 方法接受一个整数值,并返回一个新的 String,该字符串由位于指定偏移量处的单个 UTF-16 码元组成。该方法允许正整数和负整数。负整数从字符串中的最后一个字符开始倒数。
如果找不到指定的索引,则返回 undefined 。
chatAt() 方法返回一个由给定索引处的单个 UTF-16 码元构成的新字符串。
如果 index 超出了 0 – str.length - 1 的范围,charAt() 将返回一个空字符串。
normalize() 方法
某些 Unicode 字符可以有多种编码方式。有的字符既可以通过一个 BMP 字符表示,也可以通过一 个代理对表示。即使字符看起来是一样的,使用比较操作符也会返回 false。
(具体细节需自行查看,书中不做更多解释)为解决这个问题,Unicode 提供了 4 种规范化形式,可以将类似上面的字符规范化为一致的格式,无论底层字符的代码是什么。可以使用 normalize()方法对字符串应用规范化形式,使用时需要传入表示哪种形式的字符串:"NFD"、"NFC"、"NFKD"或"NFKC"。
字符串操作方法
拼接字符串:concat()
用于将一个或多个字符串拼接成一个新字符串。但更常用的方式是使用加号操作符(+)。
提取字符串:slice()、substring()
slice() 方法提取字符串的一部分,并将其作为新字符串返回,而不修改原始字符串。
substring() 方法返回该字符串从起始索引到结束索引(不包括)的部分,如果未提供结束索引,则返回到字符串末尾的部分。
slice(indexStart, indexEnd?)
substring(indexStart, indexEnd?)
substr() 作为早期方法,已弃用,存在兼容性问题。
substring() 和 slice() 之间的区别:
substring()和slice()方法几乎相同,但在处理负数参数时有一些细微差别。- 如果两个参数中的任何一个或两个都是负数或
NaN,substring()方法将把它们视为0。 slice()方法也将NaN参数视为0,但当给定负值时,它会从字符串的末尾开始反向计数以找到索引。
- 如果两个参数中的任何一个或两个都是负数或
substring()方法在indexStart大于indexEnd的情况下会交换它的两个参数,这意味着仍会返回一个字符串。而slice()方法在这种情况下返回一个空字符串。
字符串位置方法
定位子字符串:indexOf() 和 lastIndexOf()
两者的区别在于,indexOf()方法 从字符串开头开始查找子字符串,而 lastIndexOf()方法从字符串末尾开始查找子字符串。
这两个方法都可以接收可选的第二个参数,表示开始搜索的位置。
字符串包含方法
startsWith()、endsWith() 和 includes()
这 3 个方法用于判断字符串中是否包含另一个字符串。
需要注意,这3个方法都接收可选的第二个参数:
startsWith()和 includes()方法的第二个参数,表示开始搜索的位置;
endsWith()方法的第二个参数,表示应该当作字符串末尾的位置。
移除字符串前后空格
trim()
trim()方法会创建字符串的一个副本,移除前、 后所有空格符,再返回结果。
trimStart() 和 trimEnd()
trimStart() 和 trimEnd()方法分别用于从字符串开始和末尾移除空格符,并返回一个新的字符串,而不会修改原始字符串。
复制字符串
repeat()
repeat() 方法构造并返回一个新字符串,其中包含指定数量的所调用的字符串副本,这些副本连接在一起。
padStart() 和 padEnd()
padStart() 和 padEnd()方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件。 这两个方法的第一个参数是长度, 第二个参数是可选的填充字符串, 默认为空格(U+0020)。
`可选的第二个参数并不限于一个字符。如果提供了多个字符的字符串,则会将其拼接并截断以匹配 指定长度。此外,如果长度小于或等于字符串长度,则会返回原始字符串。
字符串迭代与解构
String.prototype[@@iterator]()
字符串的原型上暴露了一个@@iterator 方法,表示可以迭代字符串的每个字符。
for-of 循环
在 for-of 循环中可以通过这个迭代器按序访问每个字符。
展开语法...
有了这个迭代器之后,字符串就可以使用展开语法符来生成一个字符数组了。
字符串大小写转换
toLowerCase() 、toUpperCase()
toLocaleLowerCase()、 toLocaleUpperCase()
字符串模式匹配方法
match() 和 matchAll()
match() 方法检索字符串与正则表达式进行匹配的结果。 match() 方法本质上跟 RegExp 对象的 exec()方法相同。
matchAll() 方法返回一个迭代器,该迭代器包含了检索字符串与正则表达式进行匹配的所有结果(包括捕获组)。
search()
search() 方法用于在 String 对象中执行正则表达式的搜索,寻找匹配项。
replace() 和 replaceAll()
为简化子字符串替换操作,ECMAScript 提供了 replace()方法。
replace() 方法返回一个新字符串,其中一个、多个或所有匹配的 pattern 被替换为 replacement。pattern 可以是字符串或 RegExp,replacement 可以是字符串或一个在每次匹配时调用的函数。如果 pattern 是字符串,则只会替换第一个匹配项。原始的字符串不会改变。
replaceAll() 方法返回一个新字符串,其中所有匹配 pattern 的部分都被替换为 replacement。
replace(pattern, replacement)
replaceAll(pattern, replacement)
split()
split() 方法接受一个模式,通过搜索模式将字符串分割成一个有序的子串列表,将这些子串放入一个数组,并返回该数组。
比较字符串
localeCompare()
localeCompare() 方法返回一个数字,表示参考字符串在排序顺序中是在给定字符串之前、之后还是与之相同。在支持 Intl.Collator API 的实现中,该方法仅是调用了 Intl.Collator 方法。
当比较大量字符串时,例如对大型数组进行排序,最好创建一个 Intl.Collator 对象,并使用其 compare() (en-US) 方法提供的函数。
其他方法
isWellFormed() 和 toWellFormed()
isWellFormed() 方法返回一个表示该字符串是否包含单独代理项的布尔值。
toWellFormed() 方法返回一个字符串,其中该字符串的所有单独代理项都被替换为 Unicode 替换字符 U+FFFD。
String.raw()
String.raw() 静态方法是模板字符串的标签函数。它的作用类似于 Python 中的 r 前缀或 C# 中用于字符串字面量的 @ 前缀。它用于获取模板字符串的原始字符串形式——即,替换表达式(例如 ${foo})会被替换处理,但转义序列(例如 \n)不会被处理。
// Create a variable that uses a Windows
// path without escaping the backslashes:
const filePath = String.raw`C:\Development\profile\aboutme.html`;
console.log(`The file was uploaded from: ${filePath}`);
// Expected output: "The file was uploaded from: C:\Development\profile\aboutme.html"
HTML 方法(不推荐)
早期的浏览器开发商认为使用 JavaScript 动态生成 HTML 标签是一个需求。因此,早期浏览器扩展 了规范,增加了辅助生成 HTML 标签的方法,如 bold()、sub()、sup()、ahchor() 等。不过这些方法基本上已经没有人使用了,因为结果通常不是语义化的标记。