I wrote quite a long post on that topic (https://blog.ditectrev.com/blog/software-development/web-development/frontend/javascript/slice-vs-substring-vs-substr-complete-javascript-string-methods-comparison), but below is a basic summary:
| Feature | `slice()` / `String.prototype.slice()` | `substring()` / `String.prototype.substring()` | `substr()` / `String.prototype.substr()` |
| --- | --- | --- | --- |
| **Syntax** | `slice(start, end)` | `substring(start, end)` | `substr(start, length)` |
| **Second Parameter** | End index (exclusive) | End index (exclusive) | Length of substring |
| **Negative Index** | Supported (counts from end) | Not supported (treated as 0) | Supported (start only) |
| **Swaps Arguments** | No | Yes (if start \> end) | No |
| **Start \> End** | Returns empty string | Swaps arguments | N/A (second param is length, not end index) |
| **ECMAScript Version** | ES3+ (modern standard) | ES1 (legacy) | Not part of standard |
| **Specification** | Part of official JavaScript spec | Part of official JavaScript spec | Not part of ECMAScript standard |
| **Array API Consistency** | Consistent with `Array.slice()` | N/A | N/A |
| **NaN Handling** | NaN treated as 0 | NaN treated as 0 | NaN treated as 0 |
| **Type Coercion** | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) |
| **Status** | Recommended ✅ | Legacy ⚠️ | Deprecated ❌ |
I wrote quite a long post on that topic (https://blog.ditectrev.com/blog/software-development/web-development/frontend/javascript/slice-vs-substring-vs-substr-complete-javascript-string-methods-comparison), but below is a basic summary:
| Feature | `slice()` / `String.prototype.slice()` | `substring()` / `String.prototype.substring()` | `substr()` / `String.prototype.substr()` |
| --- | --- | --- | --- |
| **Syntax** | `slice(start, end)` | `substring(start, end)` | `substr(start, length)` |
| **Second Parameter** | End index (exclusive) | End index (exclusive) | Length of substring |
| **Negative Index** | Supported (counts from end) | Not supported (treated as 0) | Supported (start only) |
| **Swaps Arguments** | No | Yes (if start \> end) | No |
| **Start \> End** | Returns empty string | Swaps arguments | N/A (second param is length, not end index) |
| **ECMAScript Version** | ES3+ (modern standard) | ES1 (legacy) | Not part of standard |
| **Specification** | Part of official JavaScript spec | Part of official JavaScript spec | Not part of ECMAScript standard |
| **Array API Consistency** | Consistent with `Array.slice()` | N/A | N/A |
| **NaN Handling** | NaN treated as 0 | NaN treated as 0 | NaN treated as 0 |
| **Type Coercion** | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) | Same for all: coerces non-numbers to numbers (NaN/undefined/null → 0) |
| **Status** | Recommended ✅ | Legacy ⚠️ | Deprecated ❌ |