JavaScript / TypeScript 字符串方法

按“概念 -> 常用方法 -> 实战注意点”整理 String.prototype:查/取/改三类方法、常见混淆点、Unicode 坑。

#resource / javascript #resource / ecmascript #type / concept #status / growing

[!info] related notes ECMAScript MOC ECMAScript正则表达式 JS 字符串:slice / substring / at / charAt 边界差异 JS 字符串:replace / replaceAll / 正则替换 JS 字符串与 Unicode:length、surrogate pair、正确拆分

JavaScript / TypeScript 字符串方法

1) 结论:JS 和 TS 的字符串方法几乎一样

TypeScript 没有发明新的字符串方法,只是给 JavaScript 的 String.prototype 加了类型标注。

const name: string = "hello";
const upper = name.toUpperCase(); // string

2) 字符串的本质:不可变(immutable)

字符串方法不会修改原字符串,而是返回新字符串。

let str = "hello";
str.toUpperCase();
console.log(str); // "hello"

str = str.toUpperCase();
console.log(str); // "HELLO"

3) 常用方法按三类记:查 / 取 / 改

3.1 查

  • 有没有:includes()
  • 在哪:indexOf() / lastIndexOf()
  • 开头/结尾:startsWith() / endsWith()

3.2 取

  • 取字符:at() / charAt() / []
  • 取片段:slice()(优先掌握)

3.3 改(返回新字符串)

  • 替换:replace() / replaceAll()
  • 大小写:toUpperCase() / toLowerCase()
  • 去空格:trim() / trimStart() / trimEnd()
  • 拆分:split()

4) 长度和取字符

4.1 length(属性)

"hello".length; // 5

4.2 charAt / [] / at 的差异

const s = "hello";

s.charAt(100); // ""
s[100];        // undefined
s.at(-1);      // "o" (supports negative index)

结论:现代代码里更常用 []at()

更完整的差异表与例子:JS 字符串:slice / substring / at / charAt 边界差异

5) 查找内容

5.1 includes vs indexOf

  • includes 更像问“有没有”
  • indexOf 更像问“在哪”
const s = "hello world";
s.includes("world");   // true
s.indexOf("world");    // 6

5.2 search(正则)

只要是纯字符串查找,优先 includes/indexOf;需要正则再用 search

"hello 123".search(/\d/); // 6

6) 截取字符串(重点)

6.1 slice(推荐)

特性:支持负数;语义更直观。

const s = "hello world";
s.slice(0, 5);   // "hello"
s.slice(6);      // "world"
s.slice(-5);     // "world"

规则:包含 start,不包含 end。

6.2 substring(不支持负数 + 会交换)

const s = "hello";
s.substring(4, 1); // "ell"
s.slice(4, 1);     // ""

6.3 substr(历史遗留,不推荐)

substr(start, length) 在新代码里尽量不要用了。

更完整的差异表与例子:JS 字符串:slice / substring / at / charAt 边界差异

7) 替换

7.1 replace vs replaceAll

"a-b-c".replace("-", "_");      // "a_b-c"
"a-b-c".replaceAll("-", "_");   // "a_b_c"
"a-b-c".replace(/-/g, "_");      // "a_b_c"

7.2 replace 的函数替换(很实用)

const str = "hello world";
const result = str.replace(/\b\w+\b/g, (word) => word.toUpperCase());
// "HELLO WORLD"

更系统的 replace/replaceAll/捕获组:JS 字符串:replace / replaceAll / 正则替换

8) 拆分与拼接

8.1 split

"a,b,c".split(",");
"hello".split("");
"a,b,c".split(",", 2);

8.2 concat

知道即可,现代项目更常用 + 或模板字符串。

9) 去空格

"  hello  ".trim();
"  hello  ".trimStart();
"  hello  ".trimEnd();

10) 正则相关:match / matchAll

  • match(/\d+/):第一个匹配
  • match(/\d+/g):所有匹配(结构不同)
  • matchAll():拿到所有匹配 + 捕获组 + 索引(迭代器)

更系统的正则笔记:ECMAScript正则表达式

11) 编码与 Unicode 坑(面试/实战常问)

JavaScript 字符串底层是 UTF-16 编码单元序列:

  • length 统计的是编码单元数量,不一定等于“用户看到的字符数”
"😊".length; // 2

相关方法:

  • charCodeAt(i):UTF-16 code unit
  • codePointAt(i):Unicode code point(处理 surrogate pair 更合理)

更系统的 Unicode 笔记:JS 字符串与 Unicode:length、surrogate pair、正确拆分

12) TS 里的额外注意点

12.1 联合类型要先缩小

function print(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase());
  }
}

12.2 字面量类型会变宽

const s = "hello"; // "hello"
const upper = s.toUpperCase(); // string

13) 常用方法速查表

类别方法/属性作用
长度length获取长度
取字符charAt() / at() / []取字符
查找includes()是否包含
查找indexOf() / lastIndexOf()查位置
前后缀startsWith() / endsWith()判断前缀后缀
截取slice() / substring()截取子串
替换replace() / replaceAll()替换
大小写toUpperCase() / toLowerCase()转大小写
去空格trim() / trimStart() / trimEnd()去空白
拆分split()字符串转数组
正则match() / matchAll() / search()正则相关
编码charCodeAt() / codePointAt()编码
比较localeCompare()本地化比较

14) 优先掌握的 10 个

  • length
  • includes
  • indexOf
  • startsWith
  • endsWith
  • slice
  • replace
  • split
  • trim
  • toUpperCase / toLowerCase
创建于 2026/3/16 更新于 2026/5/27