Javascript截取字符串函数比较
JavaScript 字符串截取函数对比
字符串截取是前端开发中最常用的操作之一——处理用户输入、提取URL参数、生成文本摘要、截取文件名……几乎每天都要用到。但JavaScript里的截取函数有好几个,
slice()、substring()、还有已经废弃的substr(),很多人经常搞混它们的区别,尤其是对负数参数的处理,一不小心就踩坑。
今天就把这几个函数的语法、区别、使用场景、避坑指南全部分享出来,一篇文章帮你彻底搞懂字符串截取。
一、先搞懂:JavaScript 有哪些常用的字符串截取函数?
JavaScript 中用于截取字符串的核心函数有三个(按推荐程度排序):
- **
slice()**:最推荐,最灵活,对负数参数支持最好; - **
substring()**:经典方法,参数规则特殊,不支持负数索引; - **
substr()**:已废弃(ECMAScript 标准已移除),但老代码中仍常见,不推荐在新项目中使用。
重要前提:所有这些方法都不会修改原字符串,而是返回一个新的截取后的字符串,这是字符串不可变特性的体现。
二、逐个详解:语法、参数与实战例子
1. slice():最推荐的全能选手
slice() 是目前最推荐使用的字符串截取方法,它的语法直观,对负数参数的处理符合直觉,几乎能覆盖所有场景。
语法
1 | |
- **
startIndex**:必需,截取的起始索引(包含该位置的字符); - **
endIndex**:可选,截取的结束索引(不包含该位置的字符);如果省略,默认截取到字符串末尾。
核心特点
- 支持负数索引:负数表示从字符串末尾开始计数,
-1是最后一个字符,-2是倒数第二个,以此类推; - 如果
startIndex > endIndex,返回空字符串; - 不修改原字符串。
实战例子
1 | |
2. substring():经典但规则特殊
substring() 是早期 JavaScript 中常用的截取方法,它的参数规则比较特殊,尤其是对负数和参数顺序的处理,容易踩坑。
语法
1 | |
- **
startIndex**:必需,截取的起始索引(包含该位置的字符); - **
endIndex**:可选,截取的结束索引(不包含该位置的字符);如果省略,默认截取到字符串末尾。
核心特点
- 不支持负数索引:任何负数参数都会被自动转换为
0; - 如果
startIndex > endIndex,会自动交换两个参数的位置; - 不修改原字符串。
实战例子
1 | |
3. substr():已废弃,不推荐使用
substr() 的语法和前两个不同,它是通过「起始索引 + 截取长度」来截取的,虽然很多浏览器还支持,但 ECMAScript 标准已经将其移除,新项目绝对不要用,仅在维护老代码时了解即可。
语法
1 | |
- **
startIndex**:必需,截取的起始索引(包含该位置的字符);支持负数(从末尾开始计数); length:可选,截取的字符长度;如果省略,默认截取到字符串末尾;不能为负数。
核心特点
- 已废弃,不推荐使用;
startIndex支持负数,但length不支持负数;- 不修改原字符串。
实战例子
1 | |
三、核心对比:一张表搞懂所有区别
为了更直观地对比,我把三个方法的核心差异整理成了表格:
| 特性 | slice() | substring() | substr()(已废弃) |
|---|---|---|---|
| 参数规则 | (start, end) |
(start, end) |
(start, length) |
| 负数 start | 从末尾计数(-1=最后一个) | 自动转换为 0 | 从末尾计数(-1=最后一个) |
| 负数 end/length | 从末尾计数 | 自动转换为 0 | 返回空字符串(或报错) |
| start > end | 返回空字符串 | 自动交换参数位置 | 正常截取(只要 length 合法) |
| 是否废弃 | ❌ 否(推荐使用) | ❌ 否(可用但不推荐优先) | ✅ 是(ECMAScript 已移除) |
| 推荐指数 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐(仅老代码维护) |
四、使用场景建议:什么时候用哪个?
1. 优先使用 slice()(90%的场景都选它)
slice() 是最灵活、最符合直觉的方法,以下场景优先用它:
- 需要从字符串末尾截取(用负数索引,比如截取文件后缀名:
str.slice(-3)); - 参数可能是动态计算的(不用担心 start > end 的问题,直接返回空字符串,逻辑更可控);
- 代码可读性要求高(负数索引的语义更清晰)。
典型例子:截取文件后缀名
1 | |
2. 谨慎使用 substring()(仅在特殊场景)
substring() 可以用,但不是首选,仅在以下场景考虑:
- 维护老代码,原有逻辑已经用了
substring(); - 需要「自动交换参数」的特性(虽然这个特性很容易导致逻辑混乱)。
3. 绝对不要用 substr()(新项目禁止)
substr() 已经被标准废弃,虽然浏览器还支持,但随时可能有兼容性问题,新项目一律不要用,老代码也建议逐步替换为 slice()。
五、避坑指南:90%的人都会踩的坑
1. 混淆 slice() 和 substring() 的负数处理
这是最常见的坑!比如想从倒数第3个字符截取到末尾:
1 | |
2. 忘记字符串索引从 0 开始
字符串的索引是从 0 开始的,不是 1,这是新手最容易犯的错误:
1 | |
3. 以为这些方法会修改原字符串
再次强调:所有字符串截取方法都不会修改原字符串,必须用变量接收返回值:
1 | |
4. substr() 的 length 参数为负数
虽然部分浏览器会返回空字符串,但这是未定义行为,绝对不要这么写:
1 | |
六、扩展:除了这三个,还有哪些截取技巧?
除了上面的核心方法,还有一些常用的截取技巧,配合其他字符串/数组方法使用,能解决更复杂的场景:
1. 截取指定字符之前/之后的内容
结合 indexOf() 或 lastIndexOf():
1 | |
2. 按分隔符截取(split() + 数组操作)
如果需要按特定字符(如逗号、空格)截取成多段,用 split() 更方便:
1 | |
3. ES6+ 的字符串方法补充
startsWith()/endsWith():判断字符串是否以某字符开头/结尾(配合截取使用);includes():判断字符串是否包含某字符;padStart()/padEnd():补全字符串(虽然不是截取,但常和截取配合)。
七、总结
最后给大家一个最终的使用建议:
- **90%的场景,直接用
slice()**:它最灵活,对负数支持最好,逻辑最清晰; - 维护老代码时,
substring()可以保留,但不要在新逻辑中用; substr()彻底放弃:新项目绝对不要用,老代码逐步替换为slice();- 复杂场景配合
indexOf()、split()等方法:不要只盯着截取函数,组合使用效率更高。
字符串截取虽然是小功能,但细节很多,掌握好它,以后再也不会在这个问题上踩坑!