这是一个经典的 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 标准- 虽然后来被加入标准,但因其命名不直观(
substrvssubstring)且功能与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


