String methods
Search, extract, format, and clean text with JavaScript string methods while remembering that every method returns a new value.
- 01Pick the right familyChoose reading, searching, formatting, replacing, or splitting methods for a text task.
- 02Predict tricky resultsExplain
sliceversussubstring, case-sensitive searches, and first-match replacement. - 03Build practical helpersClean input, zero-pad IDs, make slugs, and mask account numbers.
A toolbox for text
INTERACTIVEA string is text. A string method is a tool you call with a dot, such as name.trim() or file.endsWith(".png"). Some methods answer a question. Some pull out a piece. Some return a cleaned-up, reformatted, or replaced copy.
The most important rule is the one from the Strings lesson: strings are immutable. Methods do not edit the original string. They return a new value, so you store the result when you want to keep it.
Imagine feeding a sign into a photocopier that has buttons for “trim the edges,” “make this uppercase,” and “replace every comma.” The machine prints a new sign. It does not erase the original.
- In real life: Original paper
- In JavaScript: The original string
- In real life: Copy with the edges trimmed
- In JavaScript:
text.trim() - In real life: Copy with bigger letters
- In JavaScript:
text.toUpperCase() - In real life: The original stays in the tray
- In JavaScript: String methods return new values
Where the analogy stops: A photocopier makes paper copies, but JavaScript returns values in memory. If you do not store the returned value, the copy is simply not used.
const original = " Hello, World! ";const result = original.trim().toLowerCase();console.log(result);console.log(original);"··Hello,·World!··"none"Hello,·World!"The method returns "Hello,·World!". The original is still "··Hello,·World!··" because string methods make a new value.
Try trim(), slice(), includes(), padStart(), replaceAll(), and split(). Notice that the original value stays visible beside the result.
Read and extract pieces
STEP THROUGHStrings use zero-based indexes, just like arrays. at(index), charAt(index), and charCodeAt(index) all look at one position, but they return different kinds of answers.
"JavaScript".at(0)returns"J".at(-1)returns the last character,"t".charAt(0)also returns"J", butcharAt(-1)returns an empty string.charCodeAt(0)returns74, the UTF-16 code unit forJ. That number matters more in the Unicode & string internals lesson.
Picture the word JavaScript printed on a banner. slice cuts out a strip from a start mark up to, but not including, an end mark.
- In real life: Marks between letters
- In JavaScript: Indexes in the string
- In real life: Cut from mark 0 to mark 4
- In JavaScript:
text.slice(0, 4) - In real life: Count backward from the right edge
- In JavaScript:
text.slice(-6) - In real life: No forward strip to cut
- In JavaScript:
text.slice(4, 0)returns""
Where the analogy stops: Real scissors can cut either direction. JavaScript methods follow exact rules: slice never swaps its start and end, while substring does.
slice and substring look similar until you use negative or swapped arguments. Step through both cases and compare the printed values.
Predict the two printed lines, then step through how slice and substring treat the same arguments.
script
const piece = text.slice(-6);const other = text.substring(-6);console.log(piece);console.log(other);Search and check text
STEP THROUGHSearch methods answer “where is it?” or “is it there?” indexOf returns the first index or -1. lastIndexOf searches from the end. includes returns true or false.
All plain string searches are case-sensitive. "Hello".includes("hello") is false. When users type freely, compare normalized copies: text.toLowerCase().includes(query.toLowerCase()).
startsWith and endsWith are specialized checks. "invoice.pdf".endsWith(".pdf") is clearer than manually slicing the last four characters. Their optional position arguments let you check a smaller window of the string.
Choose a mode, predict the output, then step through the real string method calls.
script
const first = text.indexOf("Hello", 1);const hasLower = text.includes("hello");const fixed = text.toLowerCase().includes("hello");console.log(first, hasLower, fixed);Change the copy, not the original
toUpperCase() and toLowerCase() return case-changed copies. That is useful for display labels and for normalizing comparisons, but remember that human language rules can be surprising.
JavaScript follows Unicode case rules: "ß".toUpperCase() returns SS. Locale-aware methods can vary by language; in an environment with Turkish locale data, "i".toLocaleUpperCase("tr-TR") returns İ.
Use the locale methods when you are formatting human language for people. For IDs, slugs, file extensions, and comparisons you control, plain toLowerCase() is usually easier to reason about.
Format and clean text
EXAMPLESpadStart, padEnd, and repeat create predictable lengths. "7".padStart(3, "0") returns "007"; "1234".padStart(8, "*") returns "****1234"; "ab".repeat(3) returns "ababab".
trim, trimStart, and trimEnd shave whitespace from the edges. Whitespace includes spaces, tabs, newlines, and non-breaking spaces. In real JavaScript, trimming "\t\n hi \n" leaves "hi".
Replace, split, and join ideas
PLAIN STRINGSWith a string pattern, replace replaces only the first match. replaceAll replaces every match. A replacement can also be a function, which receives the matched text and returns the new text.
Regular expressions get a whole module in Stage 8. For now, prefer plain strings. One rule to know: "aaa".replaceAll(/a/, "b") throws TypeError because a regex passed to replaceAll must be global, such as /a/g.
split(separator, limit) turns a string into an array. "a,b,c".split(",", 2) returns the first two pieces. concat combines strings, although + and template literals are more common in modern code. The next lesson, Template literals & tagged templates, goes deeper on that style.
Where you will use this
REAL HELPERSMost front-end apps constantly clean, search, and format text: usernames, search boxes, order numbers, file names, URL slugs, labels, and masked account numbers.
function cleanUsername(input) { return input.trim().toLowerCase();} function orderLabel(orderNumber) { return "ORD-" + String(orderNumber).padStart(5, "0");} console.log(cleanUsername(" ADA "));console.log(orderLabel(42));| Family | What it returns | Example → result |
|---|---|---|
| Read one | A character or code unit | "JS".at(-1) → "S" |
| Extract | A new substring | "JavaScript".slice(-6) → "Script" |
| Search/check | An index or boolean | "Hello".includes("he") → false |
| Case | A case-changed copy | "ß".toUpperCase() → "SS" |
| Pad/repeat | A fixed-width or repeated copy | "7".padStart(3, "0") → "007" |
| Trim | A copy without edge whitespace | " hi ".trim() → "hi" |
| Replace | A changed copy | "a,a".replaceAll(",", " " ) → "a a" |
| Split/combine | An array or combined string | "a,b".split(",") → ["a", "b"] |
- Check whether
photo.pngends with.png - Turn order
7into007 - Clean spaces around
Ada - Read the last four characters of a card
- Turn
red,green,blueinto pieces - Check whether a code starts with
INV- - Extract the area code from
(555) 123-4567 - Replace every comma with a space
- Combine
firstandlastinto one display name
Sort each real task by the kind of method family it needs.
Common misconceptions
- “Methods edit the string.” They return new values. Assign the result if you want to keep it.
- “
includesignores case.” It is case-sensitive. Normalize both sides when needed. - “
sliceandsubstringare interchangeable.” Negatives and swapped arguments differ. - “
replacereplaces everything.” With a string pattern it replaces the first match only. - “
padStart(3, "0")adds three zeros.” The first argument is the final target length. - “Every visible character is one index.” Some Unicode text takes more than one code unit; the Unicode lesson covers that.
Practice exercises
5 EXERCISESPredict the output of the starter code.
const order = 7;
console.log(String(order).padStart(5, "0"));String(order).padStart(5, "0")String(order) makes text, then padStart(5, "0") grows it to five total characters.
What clean value should be used for comparison?
const typed = " JavaScript ";
console.log(typed.trim().toLowerCase());typed.trim().toLowerCase()The chain returns javascript: first no edge spaces, then all lowercase.
Keep this version simple: make "Hello World!" become a URL-friendly slug.
function slugify(title) {
return title.trim().toLowerCase().replaceAll(" ", "-").replaceAll("!", "");
}
console.log(slugify("Hello World!"));function slugify(title) {
return title.trim().toLowerCase().replaceAll(" ", "-").replaceAll("!", "");
}
console.log(slugify("Hello World!"));This simple slug helper avoids regex for now: it lowercases, replaces spaces with hyphens, and removes !.
Predict the masked value printed by the starter code.
const digits = "123456781234";
const last4 = digits.slice(-4);
console.log(last4.padStart(digits.length, "*"));const digits = "123456781234";
const last4 = digits.slice(-4);
console.log(last4.padStart(digits.length, "*"));The last four digits stay visible; padStart(digits.length, "*") fills the front.
Type the two outputs, separated by a comma. Use the word empty if you prefer for the blank first line.
const text = "JavaScript";
console.log(text.slice(4, 0));
console.log(text.substring(4, 0));const text = "JavaScript";
console.log(text.slice(4, 0));
console.log(text.substring(4, 0));slice(4, 0) prints an empty line. substring(4, 0) behaves like substring(0, 4) and prints Java.
Check your understanding
7 QUESTIONSQuestion 1 of 7What does trimming edge spaces print?
Read the code, then predictconst name = " Ada "; console.log(name.trim());Choose an answer to see the explanation.
Question 2 of 7Which method is best for reading the final four characters?
Choose an answer to see the explanation.
Question 3 of 7What does a case-sensitive includes check print?
Read the code, then predictconsole.log("Hello".includes("hello"));Choose an answer to see the explanation.
Question 4 of 7What does zero-padding a ticket number print?
Read the code, then predictconsole.log("7".padStart(3, "0"));Choose an answer to see the explanation.
Question 5 of 7What does replacing with a string pattern print?
Read the code, then predictconsole.log("red red".replace("red", "blue"));Choose an answer to see the explanation.
Question 6 of 7What length does split with a limit print?
Read the code, then predictconsole.log("a,b,c".split(",", 2).length);Choose an answer to see the explanation.
Question 7 of 7What does substring with swapped arguments print?
Read the code, then predictconst text = "JavaScript"; console.log(text.substring(4, 0));Choose an answer to see the explanation.
Key takeaways
- String methods either answer a question or return a new string, array, character, or number.
- The original string is unchanged unless you assign the returned value somewhere.
slicesupports negative indexes;substringclamps negatives to 0 and swaps arguments.- Plain searches are case-sensitive, and
replacewith a string pattern changes only the first match. - Use method families to choose quickly: read, extract, search, format, trim, replace, split, and combine.
String methods are JavaScript’s text toolbox: small, predictable tools that read text or return a new text value.
Up next: Template literals & tagged templates.