jsguides

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

ParameterTypeDefaultDescription
startnumberIndex where extraction begins. Negative indices count from the end of the string.
endnumberstring.lengthIndex 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() or includes() 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