134

It is mentioned on the ECMAScript standard here that :

... These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

There is also a red warning on MDN : String.prototype.substr() MDN doc

Does anyone know why (ECMAScript standard say that) programmers should not use or assume the existence of String.prototype.substr ?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
ElJackiste
  • 4,011
  • 5
  • 23
  • 36
  • 1
    I suspect `substring` is intended to replace it - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring - substring takes a start and end position which is more conventional than start + number of characters. – eddiewould Oct 04 '18 at 06:25
  • Don't know, but one reason why I'd avoid it is because the `.substring` method sounds *very* similar, but uses *end index* as a second parameter rather than *length*. Easy to mix up, probably, better to just use one method, if possible – CertainPerformance Oct 04 '18 at 06:27
  • 1
    @eddiewould - "Replace" is an odd term here, as `substring` has been in the standardized language since there was one, but `substr` never has. :-) – T.J. Crowder Oct 04 '18 at 06:29
  • 10
    So, why not add `substr` to the standards, since many prefer using *substr* over *substring*? (arguing that using a length can be easier than using an index) – Déjà vu Feb 09 '22 at 05:10
  • 3
    Replace `substr` by `slice`. Works identical with strings. – Extrange planet Aug 23 '22 at 15:29
  • 1
    @eddiewould That's not my experience at all. Usually I know in advance the length the substring that I want. For example, if I have a date like '03-Mar-2022', I know that the month is always a fixed 3 characters long, so from a code readability and maintenance perspective, specifying "3" for the substring length is way more sensible than having to specify an ending index. – Leslie Krause Nov 27 '22 at 21:29
  • 1
    slice != substr....```> "12345678".substr( -2 , 2) '78' vs "12345678".slice( -2 , 2) '' ``` – Mesh Jun 20 '23 at 10:22

3 Answers3

111

Because it's never been part of the standardized language. It wasn't in the ECMAScript 1 or 2 specs at all, and only appears in ECMAScript 3 in Section B.2 ("Additional Properties") (and subsequent editions in similar annexes through to today [ES2022 draft as of this writing]), which said:¹

Some implementations of ECMAScript have included additional properties for some of the standard native objects. This non-normative annex suggests uniform semantics for such properties without making the properties or their semantics part of this standard.

Moreover, substr is largely redundant with substring and slice, but the second argument has a different meaning.

In pragmatic terms, I'd be surprised if you found a full mainstream JavaScript engine that didn't provide it; but I wouldn't be surprised if JavaScript engines targeted at embedded/constrained environments use didn't provide it.


¹ That wording has changed more recently to:

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.


NOTE This annex describes various legacy features and other characteristics of web browser ECMAScript hosts. 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. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex define the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.


T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 65
    Is there any reason why deprecating it is better than adding it to the standardized language? If one knows the desired length of the new string, `foo.substr(startPos, newLen);` seems cleaner than `foo.substring(startPos, startPos+newLen);`; that would be especially true of `startPos` were a more complicated expression. – supercat Oct 08 '18 at 16:55
  • 3
    @supercat - It isn't deprecated, it's never been part of the standard library in the first place. As for whether it would be better to just put it in the standard library, well, that's a judgement call for TC39. Since TC39 has no policy on the standard library (e.g., should it be large or small)... (I asked once. The answer is: They can't agree on a direction, so it's all case-by-case and [externally] which way the wind is blowing and whether it's a Tuesday or not. :-) ) – T.J. Crowder Oct 08 '18 at 17:07
  • 4
    Uncertainty of direction is a major problem of design by committee. It's especially bad with C, where it's unclear whether the Standard is trying to define a core language upon which dialects can be built that are maximally suitable for a wide range of individual purposes, or to define a language that includes everything necessary to serve a majority of use cases (IMHO, the authors of the C89 rationale make it very clear they intended the former, but compiler writers treat the C Standard as the latter). IMHO, people writing language standards need to either recognize current practices... – supercat Oct 08 '18 at 17:14
  • 1
    ...or explicitly state that responsibility for doing so lies with implementations, or else perhaps recognize what current practices are while and indicate that quality implementations should uphold practices when doing so would be useful and practical, but that doing so is not required for conformance if, in an implementer's judgment, the cost of upholding a particular practice would exceed the benefits thereof. – supercat Oct 08 '18 at 17:18
  • 4
    I much prefer substr() over substring() for most of my work - it would be nice if this was just codified into the language. It would also be nice if MDN indicated that it was technically non-standard vs. deprecated. Deprecated fully suggests that it *was* valid at some point. Grep indicates a mere 9,036 references to `.substr(` in my code... yeah this needs codification of the Cow Path. – scunliffe May 11 '22 at 21:04
17

The main advantage of substr is that you can specify a negative start position! To do the same with substring is awful.

Ananké
  • 219
  • 2
  • 2
8

I've added this declaration as an ambient declaration in a top-level ambient.d.ts file:

interface String {
  /**
   * Gets a substring beginning at the specified location and having the specified length.
   * (deprecation removed)
   * @param from The starting position of the desired substring. The index of the first character in the string is zero.
   * @param length The number of characters to include in the returned substring.
   */
  substr(from: number, length?: number): string;
}

I find substr very useful. It's often a lot more concise to specify how long you want a string to be rather than the end index of the string. If substr really ever is removed from browser or Node.js JavaScript support, I suspect many of us will simply monkey-patch substr back into existence anyway.

kshetline
  • 12,547
  • 4
  • 37
  • 73
  • 6
    While I support your notion for monkey-patching it back in I'd not recommend your approach without a polyfill to jump into place in case `.substr` is suddenly not supported anymore. Simply "hiding" the deprecation notice is just reckless. – foobored May 06 '22 at 07:27