这是一个经典的 JavaScript 字符串操作面试题,考察对字符串截取方法的理解。
substring()
、substr()
和 slice()
功能相似但有重要区别。
✅ 核心区别总结
方法 | 参数 | 是否支持负数 | 状态 | 推荐度 |
---|---|---|---|---|
substring(start, end) | 起始索引,结束索引(不包含) | ❌ 负数被视为 0 | 标准方法 | ⚠️ 可用,但注意行为 |
substr(start, length) | 起始索引,截取长度 | ✅ 起始索引可为负数(从末尾算) | 已废弃 | ❌ 不推荐 |
🔍 详细对比与示例
1. substring(start, end)
- 参数:
start
(开始位置),end
(结束位置,不包含) - 如果
start > end
,会自动交换参数 - 负数或
NaN
被视为0
- 返回从
start
到end
(不包含)的子字符串
const str = "hello world";
str.substring(2, 5); // "llo"(索引 2 到 4)
str.substring(5, 2); // "llo"(自动交换 5 和 2)
str.substring(-3, 5); // "hello"(-3 被视为 0)
str.substring(6); // "world"(从索引6到末尾)
2. substr(start, length)
- 参数:
start
(开始位置),length
(要截取的字符个数) start
为负数时,表示从字符串末尾向前数length
为负数或undefined
时,返回空字符串
const str = "hello world";
str.substr(2, 5); // "llo w"(从索引2开始,取5个字符)
str.substr(-5, 3); // "wor"(从倒数第5个开始,取3个)
str.substr(6); // "world"(从索引6到末尾)
str.substr(-3); // "rld"(从倒数第3个到末尾)
✅ 为什么 substr
被废弃?
substr
是 JavaScript 1.2 引入的,但从未被纳入早期的 ECMAScript 标准- 虽然后来被加入标准,但因其命名不直观(
substr
vssubstring
)且功能与slice
重叠 - MDN 明确标记为“已废弃”,不推荐在新代码中使用
✅ 推荐替代方案:使用 slice()
slice()
是更现代、更一致的选择:
const str = "hello world";
str.slice(2, 5); // "llo"(同 substring)
str.slice(-5, -2); // "wor"(支持负数索引)
str.slice(6); // "world"
str.slice(-3); // "rld"
✅ slice()
优点:
- 支持负数索引(从末尾计算)
- 行为一致,不会自动交换参数
- 是数组和字符串的通用方法
- 推荐在所有场景中替代
substr
和substring
✅ 对比三者行为(负数处理)
表达式 | substring() | substr() | slice() |
---|---|---|---|
str.substring(-3, 5) | "hello" (-3 → 0) | ❌ 语法错误 | "llo" (-3 → 倒数第3个) |
str.substr(-3, 2) | "rl" (-3 → 倒数第3个) | "rl" | "rl" |
str.slice(-3, -1) | ❌ 语法错误 | ❌ 语法错误 | "rl" |
✅ 总结(面试回答模板)
substring(start, end)
和substr(start, length)
的主要区别是:
substring
第二个参数是结束索引(不包含),不支持负数,且会自动交换参数;substr
第二个参数是截取长度,支持负数起始索引;但
substr
已被废弃,不推荐使用。推荐统一使用
slice()
,它支持负数索引、行为一致、兼容性好,是处理字符串截取的最佳选择。📌 一句话总结:用
slice()
,弃用substr()
。
THE END