substring不支持负数索引且会静默归零或交换参数,slice支持负索引(从末尾计数)并严格按输入顺序截取,语义清晰、与数组方法一致,推荐优先使用slice。

substring() 不支持负数索引,slice() 支持且按标准语义处理。这是两者最核心的差异,源于设计目标不同:substring 专为“起始-结束”区间截取优化,slice 则继承自数组方法,统一支持负偏移。
substring() 遇负值:自动归零,不报错但会“静默修正”
当传入负数时,substring 会将其强制转为 0(无论 start 还是 end):
-
str.substring(-2, 5)等价于str.substring(0, 5) -
str.substring(1, -3)等价于str.substring(1, 0),此时自动交换参数顺序 → 实际取str.substring(0, 1) - 这种行为没有警告,也不遵循“从末尾计数”的直觉,容易引发隐蔽逻辑错误
slice() 遇负值:按长度相加,语义清晰可预测
slice 将负数解释为“从字符串末尾倒数”,即 index = str.length + negativeIndex,结果小于 0 则截断为 0,大于 length 则截断为 length:
-
str.slice(-3)→ 从倒数第 3 个字符到末尾(如"hello".slice(-3)→"llo") -
str.slice(1, -2)→ 从索引 1 开始,到倒数第 2 个字符前为止("hello".slice(1, -2)→"el") - 负值计算后若越界(如
-100),自动 clamped 到 0;若超出 length,clamped 到 length
关键区别不止于负数:参数顺序与交换逻辑也不同
即使全用非负数,二者仍有行为分歧:
-
substring(3, 1)会自动交换为substring(1, 3),始终保证 start ≤ end -
slice(3, 1)不交换,直接返回空字符串(因为起始 > 结束) - 这意味着 substring 更“宽容”,slice 更“严格遵循输入顺序”
实际建议:优先用 slice(),除非明确需要 substring 的容错特性
现代开发中,slice 是更可靠、可移植的选择:
- 它与 Array.prototype.slice() 行为一致,降低心智负担
- 负索引语义明确,适合处理末尾片段(如文件扩展名、路径最后一段)
- 若需兼容极老环境(IE8 及以下),才考虑 substring,并手动处理负值逻辑

















