What is the difference between String.slice and String.substring?

320,794

Solution 1

slice() works like substring() with a few different behaviors.

Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);

What they have in common:

  1. If start equals stop: returns an empty string
  2. If stop is omitted: extracts characters to the end of the string
  3. If either argument is greater than the string's length, the string's length will be used instead.

Distinctions of substring():

  1. If start > stop, then substring will swap those 2 arguments.
  2. If either argument is negative or is NaN, it is treated as if it were 0.

Distinctions of slice():

  1. If start > stop, slice() will return the empty string. ("")
  2. If start is negative: sets char from the end of string, exactly like substr() in Firefox. This behavior is observed in both Firefox and IE.
  3. If stop is negative: sets stop to: string.length – Math.abs(stop) (original value), except bounded at 0 (thus, Math.max(0, string.length + stop)) as covered in the ECMA specification.

Source: Rudimentary Art of Programming & Development: Javascript: substr() v.s. substring()

Solution 2

TL;DR;

  • If you know the index (the position) on which you'll stop (but NOT include), use slice().
  • If you know the length of characters to be extracted, use substr().

Otherwise, read on for a full comparison

Syntax

  • string.slice(start,end)
  • string.substr(start,length)
  • string.substring(start,end)

Note #1: slice()==substring()

What it does?

  • The slice() method extracts parts of a string and returns the extracted parts in a new string.
  • The substr() method extracts parts of a string, beginning at the character at the specified position, and returns the specified number of characters.
  • The substring() method extracts parts of a string and returns the extracted parts in a new string.

Note #2: slice()==substring()

Changes the Original String?

  • slice() Doesn't
  • substr() Doesn't
  • substring() Doesn't Note #3: slice()==substring()

Using Negative Numbers as an Argument

  • slice() selects characters starting from the end of the string
  • substr()selects characters starting from the end of the string
  • substring() Doesn't Perform

Note #3: slice()==substr()

If the First Argument is Greater than the Second

  • slice() Doesn't Perform
  • substr() since the Second Argument is NOT a position, but length value, it will perform as usual, with no problems
  • substring() will swap the two arguments, and perform as usual

The First Argument

  • slice() Required, indicates: Starting Index
  • substr() Required, indicates: Starting Index
  • substring() Required, indicates: Starting Index

Note #4: slice()==substr()==substring()

The Second Argument

  • slice() Optional, The position (up to, but not including) where to end the extraction
  • substr() Optional, The number of characters to extract
  • substring() Optional, The position (up to, but not including) where to end the extraction

Note #5: slice()==substring()

What if the Second Argument is Omitted?

  • slice() selects all characters from the start-position to the end of the string
  • substr() selects all characters from the start-position to the end of the string
  • substring() selects all characters from the start-position to the end of the string

Note #6: slice()==substr()==substring()

So, you can say that there's a difference between slice() and substr(), while substring() is basically a copy of slice().

Solution 3

Ben Nadel has written a good article about this, he points out the difference in the parameters to these functions:

String.slice( begin [, end ] )
String.substring( from [, to ] )
String.substr( start [, length ] )

He also points out that if the parameters to slice are negative, they reference the string from the end. Substring and substr doesn't.

Here is his article about this.

Solution 4

The one answer is fine but requires a little reading into. Especially with the new terminology "stop".

My Go -- organized by differences to make it useful in addition to the first answer by Daniel above:

1) negative indexes. Substring requires positive indexes and will set a negative index to 0. Slice's negative index means the position from the end of the string.

"1234".substring(-2, -1) == "1234".substring(0,0) == ""
"1234".slice(-2, -1) == "1234".slice(2, 3) == "3"

2) Swapping of indexes. Substring will reorder the indexes to make the first index less than or equal to the second index.

"1234".substring(3,2) == "1234".substring(2,3) == "3"
"1234".slice(3,2) == ""

--------------------------

General comment -- I find it weird that the second index is the position after the last character of the slice or substring. I would expect "1234".slice(2,2) to return "3". This makes Andy's confusion above justified -- I would expect "1234".slice(2, -1) to return "34". Yes, this means I'm new to Javascript. This means also this behavior:

"1234".slice(-2, -2) == "", "1234".slice(-2, -1) == "3", "1234".slice(-2, -0) == "" <-- you have to use length or omit the argument to get the 4.
"1234".slice(3, -2) == "", "1234".slice(3, -1) == "", "1234".slice(3, -0) == "" <-- same issue, but seems weirder.

My 2c.

Solution 5

The difference between substring and slice - is how they work with negative and overlooking lines abroad arguments:

substring(start, end)

Negative arguments are interpreted as zero. Too large values ​​are truncated to the length of the string:

alert("testme".substring(-2)); // "testme", -2 becomes 0

Furthermore, if start > end, the arguments are interchanged, i.e. plot line returns between the start and end:

alert("testme".substring(4, -1)); // "test"
// -1 Becomes 0 -> got substring (4, 0)
// 4> 0, so that the arguments are swapped -> substring (0, 4) = "test"

slice

Negative values ​​are measured from the end of the line:

alert("testme".slice(-2)); // "me", from the end position 2
alert("testme".slice(1, -1)); // "estm", from the first position to the one at the end.

It is much more convenient than the strange logic substring.

A negative value of the first parameter to substr supported in all browsers except IE8-.

If the choice of one of these three methods, for use in most situations - it will be slice: negative arguments and it maintains and operates most obvious.

Share:
320,794
tmim
Author by

tmim

Updated on July 08, 2022

Comments

  • tmim
    tmim almost 2 years

    Does anyone know what the difference is between these two methods?

    String.prototype.slice
    String.prototype.substring
    
  • Andy
    Andy over 12 years
    In your last note on slice(), it should be string.length - stop
  • Oriol
    Oriol over 11 years
    In your last note on slice(), I think it should be (string.length – 1) + stop or, to make it clear that it's negative, (string.length – 1) – Math.abs(stop)
  • flying sheep
    flying sheep over 11 years
    @Longpoke: String.slice was added so that there is a string method consistent to Array.slice. substring has been there forever, so they didn’t break it and added another method. Hardly a crappy decision as 1. consistency is nice and 2. it allows CoffeeScript’s slicing syntax to work on arrays and strings. @Oriol: edited it in.
  • Rick
    Rick almost 11 years
    It seems there's a performance difference between substring and slice in Firefox 22. jsperf.com/string-slice-vs-substring
  • Qwerty
    Qwerty about 10 years
    They are equaly fast in Chrome as of May 2014.
  • Max
    Max over 9 years
    I like how substring allows for interchangeable arguments.
  • user1537366
    user1537366 over 9 years
    Andy was right. stop will be set to string.length + stop if stop is negative. Remember stop is the index after the last character extracted!
  • user1537366
    user1537366 over 9 years
    @DanielVassallo You should really edit it. It's wrong.
  • IanVS
    IanVS almost 8 years
    It looks like point 5 on substr is incorrect, according to MDN: "If start is negative, substr() uses it as a character index from the end of the string. If start is negative and abs(start) is larger than the length of the string, substr() uses 0 as the start index."
  • Venryx
    Venryx about 7 years
    The last #3 point in the answer above is verifiably incorrect, but the author is not fixing it. Proof: "abc".slice(0, -1) equals "ab", NOT "a" as his answer indicates.
  • Neil Fraser
    Neil Fraser almost 7 years
    This is incorrect, substr does handle negative parameters. '0123456789'.substr(-3, 2) -> '78'
  • Killy
    Killy almost 5 years
  • goodvibration
    goodvibration almost 5 years
    Wow, how come nobody spotted that so far? The statement "If start > stop, slice() will return the empty string" is wrong. For example: 4 > -1, but "babayaga".slice(4, -1) returns "yag".
  • snuggles
    snuggles over 4 years
    @goodvibration So the problem with the answer is that rule #3 should go first or should be noted as an exception to rule #1.
  • CodeFinity
    CodeFinity almost 4 years
    @Killy Source regarding it being a legacy feature Not mentioned in your link.
  • Max
    Max over 3 years
    You summarize your lengthy answer by "substring() is basically a copy of slice()", but the question was precisely about the difference between these two. The rest of your answer misses the topic, apart the only relevant piece information "slice will swap the arguments" hidden somewhere in the middle.
  • Max
    Max over 3 years
    What you wrote is wrong AND not relevant for the question. substr() is a different function, it does NOT have parameters "start, stop" as you erroneously state in your answer: it has parameters "start, length". But the question is not at all about substr()! Fortunately a correct and complete answer was already given 9 years before...
  • Killy
    Killy over 3 years
    @CodeFinity when I wrote the post there was a comment about, but somebody removed it in july 2020 web.archive.org/web/20200704195437/https://…
  • user3342816
    user3342816 about 3 years
    @Killy: It is still in the compatibility table as well as the side-bar. There is inconsistency in the banners. No idea why someone removed it from one but not the others or vice versa. The inconsistency is a bit unfortunate. Banner is present on all the others. In short substr is part of Annex B of the ECMA standard hence not mart of the core. It gives a note for it's usage: 262.ecma-international.org/9.0/… - MDN note: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • user3342816
    user3342816 about 3 years
    @CodeFinity: My comment above for you as well :), was no room left. Here is link to current ECMA draft as well: tc39.es/ecma262/… - guess the removal of banner is due to «probably won't be removed anytime soon» in MDN link. I still find the inconsistency a bit unfortunate – should perhaps be another banner for similar cases (where not legacy, but likely to remain for quite a while.) – Personally I just realized it after the fact and am in the process of refactoring 1k lines of new code from substr to slice lol.
  • hafiz ali
    hafiz ali about 3 years
    about substr from mdn "Deprecated. Not for use in new websites."