优先使用 slice():语义清晰、负数可预测、兼容性好;substring() 仅在需参数顺序容错时考虑;substr() 已被标记为遗留,应避免使用。

直接看参数怎么用,比背规则更可靠。三个方法表面都“截字符串”,但参数含义根本不同——slice 和 substring 用起止索引,substr 用起始位置加长度。选哪个,取决于你要解决什么问题,而不是哪个看起来顺手。
看参数定义:本质不是“怎么写”,而是“代表什么”
· slice(start, end):两个都是索引位置,end 不包含,支持负数(-1 是最后一个字符)。例如 "abc".slice(-2, -1) → "b"(等价于 slice(1, 2))。
· substring(start, end):两个也都是索引位置,end 不包含,但负数一律转为 0,且 start > end 时自动交换。例如 "abc".substring(-1, 2) → "ab"(-1 变 0,实际是 substring(0, 2));"abc".substring(2, 0) → 同样是 "ab"。
· substr(start, length):第一个是索引,第二个是要取几个字符,不是结束位置。length 为负时结果为空串。例如 "hello".substr(1, 3) → "ell";"hello".substr(-3, 2) 行为不统一(Firefox 返回 "ll",IE 可能返回别的),不推荐。
看负数处理:这是最易踩坑的分水岭
· slice 的负数逻辑一致、可预测:从末尾倒数,-n 等价于 str.length - n。
· substring 对负数“一刀切”:不管 -1、-100,全当 0 处理,容易意外截出整串开头。
· substr 的 start 支持负数(类似 slice),但 length 为负就失效;更重要的是,它不是标准方法,各浏览器历史实现有差异,尤其负 start 场景。
看生产环境怎么选:不是三选一,而是“只留一个”
· 优先无条件用 slice():语义清晰(索引区间)、负数自然(取后几位超方便)、行为稳定、所有现代环境完全兼容。
· substring() 仅在一种情况值得考虑:你明确需要“参数顺序无关”的容错性(比如用户传参不可控,且你不想自己判断大小再排序),但这种情况本身说明设计可优化,不如提前校验。
· substr() 应主动回避:ECMAScript 已标记为遗留(legacy),MDN 明确建议停止使用;它和 slice/substring 参数模式混在一起,会增加团队认知成本和维护风险。
一句话收尾
日常开发中,95% 的字符串截取需求用 slice() 就够了——它不炫技,但每一步都可预期;把 substring 当备选,substr 当黑名单,代码会更干净、更少 debug 时间。

















