921

What is the difference between

alert("abc".substr(0,2));

and

alert("abc".substring(0,2));

They both seem to output “ab”.

Difference Engine
  • 10,925
  • 5
  • 18
  • 11
  • 16
    @Derek朕會功夫 Note, `substring` [outperforms all others on Chrome](http://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/22) as of late. – Steven Lu Jul 16 '13 at 21:02
  • 4
    Adding on to @Derek comment... Unlike the `slice` method, `substring` does not handle the adjustment for negative parameters. – Dzeimsas Zvirblis Jun 27 '16 at 19:08
  • 1
    I think the more important question is "why does JavaScript have both a `substr` method and a `substring` method"? This is really the preferred method of overloading? – Sinjai Jan 26 '18 at 06:11
  • 8
    As of today, MDN has a big red warning about `substr()` being what you might call "pseudo-deprecated" at the top of the docs page here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr - Does anyone have more information about this, e.g. is there any browser that is planning to actually deprecate `substr()` at any point in the future? Or as Steven Lu suggested, might there be performance disadvantages to using `substr()` going forward? – jamess Sep 17 '18 at 17:16
  • @jamess As of today there's no warning. – codekandis Oct 24 '20 at 18:25
  • 1
    @codekandis it's at the bottom table: https://i.imgur.com/BHkYWHA.png – Paul Jan 08 '21 at 11:03

10 Answers10

1008

The difference is in the second argument. The second argument to substring is the index to stop at (but not include), but the second argument to substr is the maximum length to return.

Links?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring

decpk
  • 6,314
  • 1
  • 10
  • 24
Delan Azabani
  • 73,106
  • 23
  • 158
  • 198
  • 69
    Sounds like a common source of error. Good to know the difference. Found additional comments about this here: http://rapd.wordpress.com/2007/07/12/javascript-substr-vs-substring/ – schnaader Sep 19 '10 at 11:46
  • 3
    @Pawel also when you want it to the end of the string (no second argument) – André Chalella Oct 20 '15 at 02:48
  • This is so ridiculous that I almost miss the days of developing Java applets. ('Almost', because we had to worry about IE back then.) – Michael Scheper Jul 19 '16 at 10:22
  • 4
    You should also mention the difference on the first argument, which can be negative for substr (in which case it starts from the end), but not for substring. See JefferMC answer, but it has so many less votes that a lot of people might miss this important part. – youen Jul 26 '17 at 19:46
  • 6
    As this is the by far most upvoted answer, it should probably be edited to include that `String.prototype.substr()` is deprecated... (It is defined in [Annex B](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-string.prototype.substr) of the ECMA-262 standard, whose [introduction](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers) states: "… Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. …") – T S Nov 01 '18 at 13:52
  • 3
    ```substr``` handle negative start value whereas ```substring``` doesn't: ```"Hello".substr(-2); // return "lo"``` ```"Hello".substring(-2); // return "Hello"``` – Florian Callewaert Jun 19 '19 at 07:45
  • Am I the only one who thinks the substring end parameter should point to the last character? The times I have chopped the last character off! – MortimerCat Feb 10 '21 at 10:32
350

substr (MDN) takes parameters as (from, length).
substring (MDN) takes parameters as (from, to).

Update: MDN considers substr legacy.

alert("abc".substr(1,2)); // returns "bc"
alert("abc".substring(1,2)); // returns "b"

You can remember substring (with an i) takes indices, as does yet another string extraction method, slice (with an i).

When starting from 0 you can use either method.

Hasan Sefa Ozalp
  • 2,344
  • 20
  • 27
Colin Hebert
  • 85,401
  • 13
  • 150
  • 145
44

As hinted at in yatima2975's answer, there is an additional difference:

substr() accepts a negative starting position as an offset from the end of the string. substring() does not.

From MDN:

If start is negative, substr() uses it as a character index from the end of the string.

So to sum up the functional differences:

substring(begin-offset, end-offset-exclusive) where begin-offset is 0 or greater

substr(begin-offset, length) where begin-offset may also be negative

2540625
  • 9,332
  • 5
  • 41
  • 51
JefferMC
  • 597
  • 4
  • 10
26

Another gotcha I recently came across is that in IE 8, "abcd".substr(-1) erroneously returns "abcd", whereas Firefox 3.6 returns "d" as it should. slice works correctly on both.

More on this topic can be found here.

yatima2975
  • 6,500
  • 19
  • 42
23

The main difference is that

substr() allows you to specify the maximum length to return

substring() allows you to specify the indices and the second argument is NOT inclusive

There are some additional subtleties between substr() and substring() such as the handling of equal arguments and negative arguments. Also note substring() and slice() are similar but not always the same.

  //*** length vs indices:
    "string".substring(2,4);  // "ri"   (start, end) indices / second value is NOT inclusive
    "string".substr(2,4);     // "ring" (start, length) length is the maximum length to return
    "string".slice(2,4);      // "ri"   (start, end) indices / second value is NOT inclusive

  //*** watch out for substring swap:
    "string".substring(3,2);  // "r"    (swaps the larger and the smaller number)
    "string".substr(3,2);     // "in"
    "string".slice(3,2);      // ""     (just returns "")

  //*** negative second argument:
    "string".substring(2,-4); // "st"   (converts negative numbers to 0, then swaps first and second position)
    "string".substr(2,-4);    // ""
    "string".slice(2,-4);     // ""

  //*** negative first argument:
    "string".substring(-3);   // "string"        
    "string".substr(-3);      // "ing"  (read from end of string)
    "string".slice(-3);       // "ing"        
S.Serpooshan
  • 6,368
  • 2
  • 29
  • 53
Nate Lipp
  • 350
  • 3
  • 8
  • You missed the useful "negative second argument" for `slice`: `"string".slice(2,-2); // "ri"` – Paul May 31 '20 at 19:39
9

The difference is second parameter. Their second parameters, while both numbers, are expecting two different things:

When using substring the second parameter is the first index not to include:

var s = "string";
s.substring(1, 3); // would return 'tr'

var s = "another example";
s.substring(3, 7); // would return 'ther'

When using substr the second parameter is the number of characters to include in the substring:

var s = "string";
s.substr(1, 3); // would return 'tri'

var s = "another example";
s.substr(3, 7); // would return 'ther ex'
Kmeixner
  • 1,456
  • 4
  • 20
  • 31
CurnalCurz
  • 91
  • 1
  • 2
8

The big difference is, substr() is a deprecated method that can still be used, but should be used with caution because they are expected to be removed entirely sometime in the future. You should work to remove their use from your code. And the substring() method succeeded and specified the former one.

5ervant
  • 3,928
  • 6
  • 34
  • 63
  • 2
    Can you point to a reliable source that indicates the deprecation of `substr()`? I have read it from several people, but I cannot find any information on the web that supports the statement. Plus, Mozilla does not include it on the list of deprecated/obsolete features: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features – DanielM Nov 08 '16 at 10:01
  • @DanielM As far as I remember, it was deprecated when I post this answer, maybe the article changed and it's now not deprecated *(but not sure)*.. But still recorded on some articles such as in http://sstut.com/javascript/substring-method.php as deprecated. – 5ervant Nov 08 '16 at 16:02
  • 3
    @DanielM `String.prototype.substr()` is defined in [Annex B](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-string.prototype.substr) of the ECMA-262 standard, whose [introduction](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers) states: "… Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. …" – T S Nov 01 '18 at 13:44
  • @TS `substr()` is really noted as deprecated on some documents. – 5ervant Nov 01 '18 at 17:52
  • Yes, that's what I said: It is noted as deprecated in the standard! Or don't you consider "should not use or assume the existence of these features" as deprecated? OK, they don't use the word "deprecated", but the description seems very clear to me... – T S Nov 01 '18 at 17:56
  • The Mozilla document you link to says while substr is not strictly deprecated it is considered a legacy function and should be avoided when possible. Worth mentioning so not sure why you were downvoted. – julian Jan 10 '19 at 02:57
  • @julian Because they can't see `substr()` on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features after this answer has been made. – 5ervant Jan 10 '19 at 05:04
  • 2
    This should be the an accepted answer as of today. Using legacy functions when there's alternative is not an option for good code. Please upvote this answer to make it more visible as Google leads to this page. – vbezhenar Mar 14 '19 at 09:33
6

substring(): It has 2 parameters "start" and "end".

  • start parameter is required and specifies the position where to start the extraction.
  • end parameter is optional and specifies the position where the extraction should end.

If the end parameter is not specified, all the characters from the start position till the end of the string are extracted.

var str = "Substring Example";
var result = str.substring(0, 10);
alert(result);

Output : Substring

If the value of start parameter is greater than the value of the end parameter, this method will swap the two arguments. This means start will be used as end and end will be used as start.

var str = "Substring Example";
var result = str.substring(10, 0);
alert(result);

Output : Substring

substr(): It has 2 parameters "start" and "count".

  • start parameter is required and specifies the position where to start the extraction.

  • count parameter is optional and specifies the number of characters to extract.

var str = "Substr Example";
var result = str.substr(0, 10);
alert(result);


Output : Substr Exa

If the count parameter is not specified, all the characters from the start position till the end of the string are extracted. If count is 0 or negative, an empty string is returned.

var str = "Substr Example";
var result = str.substr(11);
alert(result);

Output : ple
raju poloju
  • 99
  • 1
  • 2
3

substring(startIndex, endIndex(not included))

substr(startIndex, how many characters)

const string = 'JavaScript';

console.log('substring(1,2)', string.substring(1,2)); // a
console.log('substr(1,2)', string.substr(1,2)); // av
Sajith Mantharath
  • 1,569
  • 1
  • 13
  • 16
0
let str = "Hello World"

console.log(str.substring(1, 3))  // el -> Excludes the last index
console.log(str.substr(1, 3))  // ell -> Includes the last index
Gaurav Singh
  • 756
  • 11
  • 24