12

substr() handles negative indices perfectly but substring() only accepts nonnegative indices.

Is there a reason of not using substr in favor of substring? The usage of negative indices are so useful in a lot of cases by viewing the space of indices as cyclic group. Why substr is indicated "deprecated" by MDN?

Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
Kaa1el
  • 337
  • 3
  • 10
  • 5
    http://stackoverflow.com/questions/3745515/what-is-the-difference-between-substr-and-substring – j08691 Aug 26 '16 at 20:52
  • 1
    @j08691 Where does that post explain why `substring()` doesn't accept negative indices? I can't find it. – showdev Aug 26 '16 at 20:59
  • 1
    @showdev That was not his question. He merely pointed that out, however his question was "Is there a reason of not using `substr` in favor of `substring`?" In the link j08691 posted, someone mentions that `substring` out-performs all alternatives. In regards to why `substr` is "deprecated", I'd assume it's simply because `substring` is a better-performing alternative. – Tyler Roper Aug 26 '16 at 21:02
  • 2
    @TylerRoper The questions I see are: "Why substring does not handle negative indices?", "Is there a reason of not using substr in favor of substring?", "Why substr is indicated 'deprecated' by MDN?" In my opinion, explaining the difference between the two functions doesn't really answer any of those questions. But maybe those answers are too opinion-based. – showdev Aug 26 '16 at 21:05
  • @showdev Not sure where you're seeing "Why substring does not handle negative indices?" being as he never said that. I think all the answers are really one simple answer: `substring` performs better *because* it doesn't use negative indices, and is probably deprecated because it is out-performed by its alternative. **EDIT:** Facepalm! @showdev is correct, it's the post title. Although I'd assume the latter portion of my answer somewhat answers the question anyways. – Tyler Roper Aug 26 '16 at 21:06
  • 1
    @TylerRoper It's the title of the post. Anyway, I'm not that worried about it. I was just curious. – showdev Aug 26 '16 at 21:06
  • @showdev Well duh -_- not sure how I missed that. Edited my comment, apologies! – Tyler Roper Aug 26 '16 at 21:08

3 Answers3

7

substring is when you want to specify a starting and ending index. substr is when you want to specify a starting offset and a length. They do different things and have different use cases.

Edit: To better answer the exact question of
Why substring does not handle negative indices?

substring specifies a starting and ending index of characters in a string. substr deals with a starting offset and a length. It makes sense to me that substring does not allow a negative index, because there really isn't a such thing as a negative index (the characters in a string are indexed from 0 to n, a "negative index" would be out of bounds). Since substr is dealing with an offset vs an index, I feel the term offset is loose enough to allow for a negative offset, which of course means counting backwards from the end of the string rather than forward from the beginning. This might just be semantics, but its how I make sense of it.

Why is substr deprecated?

I would argue that is in fact not deprecated.

The revision history for the substr MDN states the deprecation notice was put in based on this blog post:

Aug 16, 2016, 12:00:34 AM hexalys add deprecated mention per https://blog.whatwg.org/javascript

Which states that the HTML string methods are deprecated (which they should be!). These are methods that wrap a string in an HTML tag, ie, "abc".sub() would return <sub>abc</sub>. The blog post lists out all of the HTML string methods, and imho, erroneously includes subtr as an HTML string method (it isn't).

So this looks like a misunderstanding to me.

(Excerpt below, emphasis added by me)

Highlights:

The infamous “string HTML methods”: String.prototype.anchor(name), String.prototype.big(), String.prototype.blink(), String.prototype.bold(), String.prototype.fixed(), String.prototype.fontcolor(color), String.prototype.fontsize(size), String.prototype.italics(), String.prototype.link(href), String.prototype.small(), String.prototype.strike(), String.prototype.sub(), String.prototype.substr(start, length), and String.prototype.sup(). Browsers implemented these slightly differently in various ways, which in one case lead to a security issue (and not just in theory!). It was an uphill battle, but eventually browsers and the ECMAScript spec matched the behavior that the JavaScript Standard had defined.

https://blog.whatwg.org/javascript

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • 2
    Additional evidence: here's the [entry in the ES2015 spec](http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.substr) stating it's "required when the ECMAScript host is a web browser. [substr] is normative but optional if the ECMAScript host is not a web browser." There's also an entry in the [ES2015 spec.](http://www.ecma-international.org/ecma-262/7.0/#sec-string.prototype.substr) – Mike Cluck Aug 26 '16 at 21:18
3

substr is particularly useful when you are only interested in the last N characters of a string of unknown length.

For example, if you want to know if a string ends with a single character:

function endsWith(str, character) {
  return str.substr(-1) === character;
}

endsWith('my sentence.', '.'); // => true
endsWith('my other sentence', '.'); // => false

Implementing this same function using substring would require you calculating the length of the string first.

function endsWith(str, character) {
  var length = str.length;
  return str.substring(length - 1, length) === character;
}

Both functions can be used to get the same results, but having substr is more convenient.

Steven Schobert
  • 4,201
  • 3
  • 25
  • 34
  • I'm not sure how this answers any of the posted questions. Am I missing something? "Why substring does not handle negative indices?", "Is there a reason of not using substr in favor of substring?", "Why substr is indicated 'deprecated' by MDN?" – showdev Aug 26 '16 at 21:02
  • I was trying to answer the question "why use X over Y" by drawing a distinction between them. One other distinction I didn't cover is the fact that `substring` uses an index as the last argument instead of length, which is particular useful if you are already dealing with the indices of strings. – Steven Schobert Aug 26 '16 at 21:12
  • @showdev I agree with your comment above though, that that kind of a question is primarily opinion based, so maybe my answer doesn't belong. – Steven Schobert Aug 26 '16 at 21:14
3

There are three functions in JS that do more or less the same:

  • substring
  • substr
  • slice

I guess most people use the latter, because it matches its array counterpart. The former two are more or less historical relicts (substring was in JS1, then substr came in two different flavours etc).

Why substr is indicated "deprecated" by MDN?

The notice has been added as per this post by Mathias where substr is listed under "string HTML methods" (?). The reason of the deprecation is that it belongs to the Annex B which says:

This annex describes various legacy features and other characteristics of web browser based ECMAScript implementations. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification.

Community
  • 1
  • 1
georg
  • 211,518
  • 52
  • 313
  • 390
  • 1
    It's deprecated from the language at large but is actually *required* for browser environments. "The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser." [Source](http://www.ecma-international.org/ecma-262/6.0/#sec-additional-ecmascript-features-for-web-browsers) – Mike Cluck Aug 26 '16 at 21:25
  • @MikeC: it's only required to support legacy. Shouldn't be used in the new code. – georg Aug 26 '16 at 21:39
  • I'm not disagreeing. I'm just saying that it technically is defined and specified for browser usage. – Mike Cluck Aug 26 '16 at 21:40