String.prototype.slice()
slice(start[, end]) slice() extracts a portion of a string and returns it as a new string. The original string remains unchanged. This method is useful when you need to extract substrings based on positions, whether counting from the start or from the end using negative indices.
Syntax
slice(start)
slice(start, end)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
start | number | — | Index where extraction begins. Negative indices count from the end of the string. |
end | number | string.length | Index where extraction ends (exclusive). Negative indices count from the end. |
Examples
Extracting from the start
const greeting = "Hello, World!";
// Extract first 5 characters
console.log(greeting.slice(0, 5));
// Hello
// Omitting end extracts to the end of the string
console.log(greeting.slice(7));
// World!
When both arguments are positive, slice() works like an array slice: start is inclusive and end is exclusive. If you omit end, the method extracts from start through the end of the string, which is a concise way to grab a suffix when you know the split point. Negative indices give you the same control from the other direction.
Using negative indices
const text = "Hello, World!";
// Extract last 6 characters
console.log(text.slice(-6));
// World!
// Extract middle portion using negative end index
console.log(text.slice(0, -1));
// Hello, World
Negative indices count backward from the end: -1 means the last character, -6 means six characters from the end. This is one of the main reasons to prefer slice() over substring(), which treats negatives as zero. Edge cases around the bounds are also well-defined.
When start exceeds length
const str = "Hello";
// If start is greater than or equal to string length, returns empty
console.log(str.slice(10));
// (empty string)
console.log(str.slice(5));
// (empty string)
If start is at or past the end of the string, slice() returns an empty string rather than throwing. This makes it safe to use with computed indices without first checking bounds. The same principle applies when start exceeds end.
Start greater than end
const str = "Hello";
// When start is greater than end, slice() returns empty string
console.log(str.slice(5, 0));
// (empty string)
When start is greater than end, the result is always empty. There is no argument swapping, unlike substring(). This consistency makes the behavior easier to predict in loops or computed-position scenarios. Knowing these fundamentals, you can combine slice() with other string methods for practical tasks.
Common Patterns
Extract file extension from filename
const filename = "report.pdf";
const ext = filename.slice(filename.lastIndexOf("."));
console.log(ext);
// .pdf
Pairing slice() with lastIndexOf() is a common pattern for splitting filenames at the final dot. The dot itself is included in the result, which is usually what you want for an extension string. When you only care about the characters at the far end of a string, a negative start is even simpler and avoids the need for a separate index lookup. This approach removes the need to compute positions manually. Once you know the file extension, extracting the last few characters of a string is just as straightforward.
Get last N characters
const id = "user-12345";
const suffix = id.slice(-5);
console.log(suffix);
// 12345
A negative start is the simplest way to grab trailing characters. It works regardless of the string length — if the string is shorter than N, you get the whole string back, which is safer than computing length - N yourself. For UI work, the same idea powers text truncation with a fixed character limit. Setting a maximum character count and appending an ellipsis is one of the most common slice use cases in frontend code. The same technique adapts easily to any situation where you need to show a preview of longer content.
Truncate text with ellipsis
const longText = "This is a very long description that needs truncating";
const maxLength = 20;
const truncated = longText.length > maxLength
? longText.slice(0, maxLength) + "..."
: longText;
console.log(truncated);
// This is a very long...
Truncation with slice(0, maxLength) is a one-liner that reads clearly. Check the length first so you do not append an ellipsis when the text is already short enough.
Remove surrounding quotes or brackets
const quoted = "\"Hello World\"";
const unquoted = quoted.slice(1, -1);
console.log(unquoted);
// Hello World
A positive start and negative end together strip one character from each side. This pattern works for quotes, parentheses, brackets, or any paired delimiters where you know the outer characters are always present.
Extract domain from URL
const url = "https://api.example.com/v1/users";
const domain = url.slice(8, url.indexOf("/", 8));
console.log(domain);
// api.example.com
For simple URL parsing where you know the protocol is https://, slice(8) skips past it and indexOf("/", 8) finds the first path separator. This is brittle for production use — a proper URL parser handles edge cases like ports, auth, and protocol-relative URLs — but it is a useful utility for quick scripts.
When to Use
Use slice() when you need to:
- Extract substrings with precise control over start and end positions
- Work with negative indices to count from the end
- Maintain consistency with Arrayslice() behavior
Why slice() is usually the default
For new code, slice() is often the clearest substring tool because its rules are predictable: start is inclusive, end is exclusive, and negative values count from the end. That makes it easy to reason about ranges without mental argument swapping. When you are scanning code later, the API also signals that no mutation is happening. The method returns a new string and leaves the original untouched, which fits JavaScript’s immutable string model.
Handling Unicode carefully
slice() works on UTF-16 code unit positions, not on user-perceived characters. For plain ASCII text that is fine, but emoji and many other scripts can span two code units. If you slice through the middle of a surrogate pair, you can create broken text. When the content may contain international characters, use code-point-aware logic first or combine slice() with iteration that respects Unicode boundaries.
When not to use
Avoid slice() when:
- You need case-insensitive matching — use a regex or
toLowerCase()first - You’re searching for a substring by content — use
indexOf()orincludes()instead - You need the argument-swap behavior that
substring()provides
slice() vs substring() vs substr()
All three extract a portion of a string, but they differ in how they handle arguments. slice() accepts negative indices (counting from the end) and returns an empty string when start exceeds end. substring() does not accept negative indices (they are treated as 0) and automatically swaps start and end if start is greater than end. substr() is deprecated — its second argument is a length, not an end index. Prefer slice() for new code: it handles negative indices intuitively and its behavior is consistent with Array.prototype.slice().
const s = "hello";
s.slice(-3); // "llo" — last 3 characters
s.substring(-3); // "hello" — negative treated as 0
s.slice(2, 1); // "" — start > end returns empty
s.substring(2, 1); // "e" — arguments are swapped to (1, 2)
Immutability
slice() never modifies the original string — JavaScript strings are immutable. Every string method that appears to modify a string actually returns a new one. The original variable is unchanged unless you reassign it.
See Also
- String.prototype.split() — Split string into array
- String.prototype.substring() — Similar method with different index handling