请解释 String.prototype.substr() 和 String.prototype.substring() 的区别, 以及和 slice 的区别。

推荐答案

substr()substring() 以及 slice() 都是用来提取字符串一部分的方法,它们的区别主要在于参数的含义以及对负数参数的处理:

  • substr(start, length)

    • start:起始索引(可以是负数,负数表示从字符串末尾开始计数,-1为最后一个字符)。
    • length:提取的字符个数(可选,省略则提取到字符串末尾)。
    • 注意substr 在一些旧浏览器或 JavaScript 版本中可能存在兼容性问题,现在一般不太推荐使用。
  • substring(start, end)

    • start:起始索引(非负数)。
    • end:结束索引(可选,省略则提取到字符串末尾)。提取的子字符串不包括 end 索引处的字符。
    • 如果 start 大于 end,则 substring() 会自动交换两个参数。
    • 如果 startend 为负数或 NaN,则会被当作 0 处理。
  • slice(start, end)

    • start:起始索引(可以是负数,负数表示从字符串末尾开始计数,-1为最后一个字符)。
    • end:结束索引(可选,省略则提取到字符串末尾)。提取的子字符串不包括 end 索引处的字符。
    • 如果 start 大于 end,则返回空字符串。
    • 负数索引会从字符串尾部开始计算。

总结区别

方法 参数含义 负数参数处理 start > end 兼容性
substr start, length start 可为负数, 表示从末尾开始计算;length为提取长度 无特定处理 较老
substring start, end 负数或 NaN 被视为 0 交换参数
slice start, end 负数表示从末尾开始计算 返回空字符串

本题详细解读

1. 参数定义和功能

  • substr(start, length)
    • start 参数指定了子字符串开始的位置。可以是正数或负数。正数表示从字符串开头开始计数(索引从0开始),负数表示从字符串结尾开始计数(-1表示最后一个字符,-2表示倒数第二个字符,依此类推)。
    • length 参数是可选的,它指定了提取的子字符串的字符数。如果省略 length,则 substr 会提取从 start 位置到字符串结尾的所有字符。
  • substring(start, end)
    • start 参数指定了子字符串的起始位置。它必须是非负整数。
    • end 参数是可选的,它指定了子字符串的结束位置(不包含该位置的字符)。如果省略 end,则 substring 会提取从 start 位置到字符串结尾的所有字符。
  • slice(start, end)
    • start 参数指定了子字符串的起始位置。它可以是正数或负数,负数表示从字符串末尾开始计数。
    • end 参数是可选的,它指定了子字符串的结束位置(不包含该位置的字符)。 如果省略 end,则 slice 会提取从 start 位置到字符串结尾的所有字符。

2. 负数参数的处理

  • substr()start 参数可以使用负数,负数表示从字符串末尾开始计数。例如,'hello'.substr(-2, 2) 返回 'lo'
  • substring():如果 startend 是负数或者 NaN,则会被当作 0 处理。例如,'hello'.substring(-2, 4) 相当于 'hello'.substring(0, 4),返回 'hell'
  • slice()startend 都可以是负数,负数表示从字符串末尾开始计数。例如,'hello'.slice(-2) 返回 'lo''hello'.slice(-3, -1) 返回 'll'

3. start 大于 end 的情况

  • substr():当 start 大于字符串长度时,返回空字符串。 当length为负值时,也会返回空字符串。
  • substring():当 start 大于 end 时,substring 会自动交换两个参数,也就是说,'hello'.substring(3, 1) 等同于 'hello'.substring(1, 3),返回 'el'
  • slice(): 当 start 大于 end 时,slice 返回空字符串。例如, 'hello'.slice(3,1) 返回 ''

4. 兼容性

  • substringslice 都是标准方法,兼容性很好。
  • substr 在某些旧的浏览器中可能存在兼容性问题,因此在新的项目中建议使用 substringslice 来代替。

5. 使用场景建议

  • 如果你需要提取固定长度的字符串,并且起始位置可能是从字符串末尾开始计算的,那么可以考虑使用 slice,或者在知道起始索引,长度的情况下,使用 substr。
  • 如果你只需要提取两个位置之间的字符串,并且位置参数是非负的,那么可以使用 substringslice,但建议优先使用 slice
  • 在处理负数索引时,推荐使用 slice,它的行为更符合直觉。
纠错
反馈