Selecting a substring
Bracket notation reads one character. To take several consecutive characters, a substring, use the slice method:
string.slice(startIndex, endIndex)
It returns a new string made of the characters from startIndex up to, but not including, endIndex. Both indexes are zero-based.
let language = "JavaScript";
let part = language.slice(2, 6);
console.log(part);
console.log(language);
vaSc
JavaScript
The character at index 2 (v) is included, and the character at index 6 (r) is not. The original string is unchanged. Strings can't be modified, so slice builds a new string and leaves the old one alone.
A handy way to think about the end index
The end index is where the slice stops, so end - start is the length of the result. slice(2, 6) gives 4 characters. To take the first 6 characters, slice from 0 to 6. This end-exclusive convention is used throughout programming, and it makes neighbouring slices fit together: s.slice(0, 6) and s.slice(6) cover the whole string with no overlap and no gap.
Leaving out the end
If you omit endIndex, the slice runs to the end of the string:
let language = "JavaScript";
console.log(language.slice(4));
Script
Negative and out-of-range indexes
Unlike bracket notation, slice accepts negative indexes, which count back from the end of the string. Out-of-range indexes are clamped, so they don't cause errors:
let message: string = "Coding feels great";
console.log(message.slice(-5));
console.log(message.slice(-5, -2));
console.log(message.slice(0, 100));
console.log(message.slice(10, 3) === "");
great
gre
Coding feels great
true
The last line shows that a start index after the end index gives the empty string. The related method substring treats negative numbers as 0 and swaps its two arguments if the start is larger, so it behaves differently in these cases. With slice, what you see in the code is what you get.
Slicing with calculated indexes
The indexes can be any number expression, so slices adapt to the string's length. Capitalising a word takes its first letter and the rest:
const w = "coding";
console.log(w.slice(0, 1).toUpperCase() + w.slice(1));
const mid = Math.floor(w.length / 2);
console.log(w.slice(0, mid), w.slice(mid));
Coding
cod ing
The second line cuts the word into two halves. Math.floor is needed because w.length / 2 would be fractional for odd lengths, and the halves meet at mid without overlap, as explained above.
Slicing from the end
For the last n characters, s.slice(-n) and s.slice(s.length - n) agree for any n from 1 up to the length. They differ when n is 0. For "Coding feels great", slice(-0) is the same as slice(0) and returns the whole string, while slice(s.length - 0) correctly returns the empty string. If n can be zero, prefer the form with the length. In the exercise below, the last word is always 5 characters long, so either form is safe there.
The exercise
The starter code declares a message:
let message: string = "Coding feels great";
It has three words, with spaces at indexes 6 and 12.
firstWord: the first 6 characters are indexes 0 to 5, so the call isslice(0, 6).middleWord: the 8th through 12th characters are indexes 7 to 11. Since the end index is excluded, pass 12:slice(7, 12).lastWord: the last 5 characters start at index 13 and go to the end, soslice(13)is enough.slice(-5)gives the same result.
let message: string = "Coding feels great";
let firstWord: string = message.slice(0, 6);
let middleWord: string = message.slice(7, 12);
let lastWord: string = message.slice(13);
The variables hold Coding, feels and great. The lesson doesn't print them, but console.log(firstWord) would show Coding.
Gotchas
- Counting from 1. "8th through 12th" is natural language. The code needs indexes 7 and 12, not 8 and 12.
- Including the end index. Learners often write
slice(7, 11)to reach index 11, and lose the last letter. - Expecting the string to change.
message.slice(0, 6)on its own line does nothing useful, because the result is thrown away. Store it in a variable. - Using
slicewith a length. The second argument is an end position, not a count of characters, unlike in some other languages' substring functions.
Key takeaways
s.slice(start, end)includesstartand excludesend.- Omitting
endgoes to the end of the string. - Negative indexes count from the end.
- The original string never changes.