字符串的所有方法:怎么系统记?哪些是查找,哪些是截取,哪些是替换?
面试速答(30 秒版 TL;DR)
- 字符串方法最稳的记法是按 6 类:静态方法、取字符、查找判断、截取拆分、替换格式化、大小写与空白处理。
- 面试高频不是让你逐个背 API 名,而是追问:
slice/substring区别、replace/replaceAll区别、indexOf/includes区别、Unicode 代理对问题、正则相关方法怎么配合用。 - 新一些的字符串方法要会:
at、matchAll、replaceAll、isWellFormed、toWellFormed。 - 历史遗留的 HTML 包装方法如
blink、bold、link了解即可,现代开发基本不用。
版本说明
- 以 现代浏览器 + ES2024 常见
String标准库 为准。 - 这里只列
String构造器静态方法 与String.prototype实例方法。
一、String 静态方法
| 方法 | 作用 | 备注 |
|---|---|---|
String.fromCharCode(...units) | 按 UTF-16 码元创建字符串 | 老方法,不能直接处理超出 BMP 的码点 |
String.fromCodePoint(...codePoints) | 按 Unicode 码点创建字符串 | 处理 emoji 更稳 |
String.raw(strings, ...values) | 生成“保留转义字符原样”的模板字符串 | 常见于标签模板 |
String.fromCharCode(65); // "A"
String.fromCodePoint(0x1f600); // "😀"
String.raw`a\nb`; // "a\\nb"
二、取字符与字符编码
| 方法 | 返回值 | 说明 |
|---|---|---|
at(index) | 字符 / undefined | 支持负索引 |
charAt(index) | 字符 | 越界返回空字符串 |
charCodeAt(index) | UTF-16 码元 | 老接口 |
codePointAt(index) | Unicode 码点 | 处理代理对更合理 |
charCodeAt 和 codePointAt 的差别
const s = "😀";
s.length; // 2
s.charCodeAt(0); // 55357
s.codePointAt(0); // 128512
原因:JS 字符串底层按 UTF-16 码元 存储,不是所有字符都只占 1 个码元。
三、查找与判断类方法
| 方法 | 作用 |
|---|---|
includes(search, position?) | 是否包含 |
startsWith(search, position?) | 是否以某串开头 |
endsWith(search, endPosition?) | 是否以某串结尾 |
indexOf(search, fromIndex?) | 第一次出现位置 |
lastIndexOf(search, fromIndex?) | 最后一次出现位置 |
search(regexp) | 按正则查找位置 |
match(regexp) | 返回匹配结果 |
matchAll(regexp) | 返回所有匹配的迭代器 |
localeCompare(other, locales?, options?) | 本地化比较 |
includes vs indexOf
includes更适合做布尔判断,可读性更好indexOf适合既想判断,又想拿下标
"hello".includes("ell"); // true
"hello".indexOf("ell"); // 1
match vs matchAll
const text = "id=1&id=2";
text.match(/\d/g); // ["1", "2"]
[...text.matchAll(/id=(\d)/g)].map((m) => m[1]); // ["1", "2"]
结论:
- 想拿所有匹配且保留分组,优先
matchAll matchAll要配合全局正则g
四、截取、拆分与拼接
| 方法 | 作用 | 特点 |
|---|---|---|
slice(start, end?) | 截取子串 | 支持负索引 |
substring(start, end?) | 截取子串 | 不支持负索引,且会交换较大较小值 |
split(separator?, limit?) | 拆成数组 | 分隔符可为正则 |
concat(...strings) | 拼接字符串 | 现代开发更常用 + 或模板字符串 |
slice vs substring
const s = "abcdef";
s.slice(1, 4); // "bcd"
s.substring(1, 4); // "bcd"
s.slice(-2); // "ef"
s.substring(-2); // "abcdef"
面试口径:
slice更直观,也支持负索引substring更像历史接口,现代代码通常优先slice
五、替换与模式处理
| 方法 | 作用 |
|---|---|
replace(pattern, replacement) | 替换第一次匹配,或由正则决定 |
replaceAll(pattern, replacement) | 替换所有匹配 |
"a-b-c".replace("-", "_"); // "a_b-c"
"a-b-c".replaceAll("-", "_"); // "a_b_c"
"2026-03-23".replace(/\d+/g, "x"); // "x-x-x"
要点:
replace如果传字符串,只替换第一个- 想全替换可用
replaceAll,或replace(/.../g, ...) replacement也可以是函数,用来做动态替换
六、格式化与补位
| 方法 | 作用 |
|---|---|
padStart(targetLength, padString?) | 头部补齐 |
padEnd(targetLength, padString?) | 尾部补齐 |
repeat(count) | 重复字符串 |
normalize(form?) | Unicode 归一化 |
"7".padStart(3, "0"); // "007"
"ab".repeat(3); // "ababab"
normalize 的面试答法:
- 看起来一样的字符,底层可能有不同编码组合
- 归一化后再比较,结果更稳定
七、大小写与空白处理
| 方法 | 作用 |
|---|---|
toLowerCase() | 转小写 |
toUpperCase() | 转大写 |
toLocaleLowerCase(locales?) | 按地区规则转小写 |
toLocaleUpperCase(locales?) | 按地区规则转大写 |
trim() | 去两端空白 |
trimStart() | 去开头空白 |
trimEnd() | 去结尾空白 |
八、值转换与基础方法
| 方法 | 作用 |
|---|---|
toString() | 返回字符串本身 |
valueOf() | 返回原始字符串值 |
九、Unicode 健康检查
| 方法 | 作用 |
|---|---|
isWellFormed() | 判断是否为格式良好的 Unicode 字符串 |
toWellFormed() | 修复非法代理对,返回安全字符串 |
这两个方法属于“你知道会加分,但日常不是最高频”的类型。
十、历史遗留 HTML 包装方法
下面这些存在于 String.prototype,但现代开发基本不该再用:
anchorbigblinkboldfixedfontcolorfontsizeitalicslinksmallstrikesubsup
面试口径:
- 它们会返回一段 HTML 字符串
- 是很早期的浏览器时代遗留能力
- 今天不推荐使用,也不该作为业务代码方案
十一、和正则配合时的高频组合
| 目标 | 常用方法 |
|---|---|
| 判断是否匹配 | regexp.test(str) |
| 取第一个匹配 | str.match(regexp) 或 regexp.exec(str) |
| 取所有匹配和分组 | str.matchAll(regexp) |
| 替换 | str.replace / str.replaceAll |
| 查位置 | str.search(regexp) |
典型题 & 标准答法
Q1:slice 和 substring 有什么区别?
slice支持负索引substring会把负值当成0,且参数顺序颠倒时会自动交换- 现代代码优先
slice
Q2:replace 和 replaceAll 怎么选?
- 只改第一次,用
replace - 明确要全局替换,用
replaceAll - 需要正则灵活性时,也可用
replace(/pattern/g, ...)
Q3:为什么 emoji 相关字符串题容易出错?
因为 JS 字符串按 UTF-16 码元工作,一个字符不一定只占一个位置。涉及长度、切片、字符编码时,要考虑代理对。
易错点/坑
str.length是码元长度,不一定等于“人眼看到的字符数”。replace("x", "y")默认只替换第一个。substring不支持负索引。matchAll需要全局正则g。- 历史 HTML 包装方法存在,但不建议使用。
速记要点(可背诵)
- 查找判断:
includes、startsWith、endsWith、indexOf。 - 截取拆分:
slice、substring、split。 - 模式处理:
match、matchAll、search、replace、replaceAll。 - Unicode 相关:
codePointAt、fromCodePoint、normalize、isWellFormed。