JavaScript basicsStrings in plain wordsOne tool at a time
String
Toolbox
A string is a piece of text, a row of characters held in quotes. This guide shows how to read it, search it, cut it up, tidy it, replace parts of it and compare it, with a small example for each that you can run.
Key terms in plain words
Never written code before? Start here. Every word below shows up later on this page, and each one comes with an everyday comparison. Underlined words in the modules link back to these cards.
23 terms in 4 groups. Hover an underlined word anywhere on the page for a quick reminder, or click it to jump here.
What text is made of
A string works like a row of letter tiles on a board game rack. Each tile holds one character and sits in a numbered slot.
- String
- Think of it as a row of letter tiles standing on a rack
- Programmers call a piece of text a string. It can be one letter, a whole sentence or nothing at all, and you write it between quotes so the computer knows it is text and not a command.
- For example
"Namaste"is a string of seven characters. - Character
- Think of it as one tile on the rack
- A single letter, digit, space or symbol inside a string. A space counts as a character too, which is why stray spaces change the length.
- Position (index)
- Think of it as the number painted under each slot of the rack, starting from 0
- Every character has a position, and counting starts at 0, not 1. So the first character is at 0 and the last one is at the length minus one. Many tools here also let a negative number count back from the end.
- For example In
"Asha", position 0 isAand position -1 (withat) isa. - Template literal
- Think of it as a printed form with blanks that fill themselves in
- A string written between backticks instead of quotes. Anything you put inside
${ }is worked out and dropped into the text, so you don't have to glue pieces together with a plus sign. - For example `
Hi ${name}becomesHi Asha` when name is Asha. - Immutable
- Think of it as tiles glued to the rack, so you lay out a new row instead of swapping one
- Something that cannot be changed once made. Strings are immutable: no tool edits the original. Each one hands you a brand new string and leaves the old one as it was.
- Property
- Think of it as a fact printed on the side of the rack, such as how many tiles it holds
- A value that belongs to something and that you read with a dot and no brackets.
lengthis a property of every string. - For example
"Asha".lengthis 4. - Method
- Think of it as a button on the rack that does a job when you press it
- An action that belongs to a value. You write a dot, the name, then round brackets, and the brackets can carry extra details such as what to search for.
- For example
name.toUpperCase()runs the toUpperCase method on name.
Finding and cutting
Spotting a tile on the rack, lifting out a run of tiles, and breaking a row into pieces.
- True or false
- Think of it as a yes or no answer from the person checking the rack
- Many checks give back one of two answers: true or false. Programmers call this kind of value a boolean, and it is what you test in an if statement.
- For example
"asha@mail.com".includes("@")givestrue. - Case sensitive
- Think of it as a checker who treats a capital A tile and a small a tile as different letters
- Case means capital or small letters. A case sensitive search only matches the exact same capitals, so "Razor" will not find "razor". Make both sides lower case first when capitals should not matter.
- -1 for not found
- Think of it as the checker shrugging and pointing at a slot that does not exist
indexOfgives the position where your text starts. When the text is not there at all, it gives -1, because 0 is already a real position.- Slice
- Think of it as lifting out a run of tiles from one slot up to, but not including, another
- Copies part of a string between two positions. The start is included and the end is not. Leave out the end to go all the way, or use a negative number to count from the back.
- For example
"report.pdf".slice(-3)givespdf. - Array
- Think of it as a tray of separate words laid out in order
- A list of values kept in order, written between square brackets. Splitting a string gives you an array, so you can use list tools on the pieces.
- For example
["report", "2026", "09.pdf"]is an array of three strings. - Split and join
- Think of it as breaking a row of tiles wherever a dash sits, then pushing the pieces back together
splitcuts a string at every separator you name and gives an array of the pieces.joindoes the opposite: it glues array items into one string, with whatever you choose between them.- For example
"a-b-c".split("-")gives["a", "b", "c"].
Tidying and changing
Sweeping stray spaces off the rack, filling gaps and swapping tiles.
- Whitespace and trim
- Think of it as blank tiles that crept in at either end of the row
- Whitespace means spaces, tabs and line breaks: characters you can't see but the computer still counts.
trimremoves them from both ends, which is why it is the first thing to do with anything a person typed. - Padding
- Think of it as adding filler tiles until the row is a set length
padStartandpadEndadd a fill character to one end until the string reaches the length you asked for. Handy for codes like 007 or for lining up a receipt.- For example
"7".padStart(3, "0")gives007. - Replace
- Think of it as swapping one word on the rack for another
replaceswaps the first match for new text.replaceAllswaps every match. Both hand back a new string and leave the original alone.- Regular expression (regex)
- Think of it as a stencil that matches any tile of a certain kind, such as every digit
- A pattern for describing text rather than spelling it out. It sits between slashes, and a
gafter the closing slash means match every place, not just the first. - For example
/\d/gmatches every digit in a string. - Function
- Think of it as a little helper you hand instructions to, who hands a result back
- A named set of steps you can run again and again. You give it inputs in brackets and it gives back an answer. Several tools here accept your own function to decide what each piece becomes.
- For example
const shout = (s) => s.toUpperCase();is a small function.
Comparing and special characters
Deciding if two rows match, putting words in dictionary order, and handling tiles that are wider than one slot.
- Strict equality (===)
- Think of it as laying two rows side by side and checking every tile is identical
- Three equals signs ask "are these exactly the same?". For strings, a single different capital or accent makes the answer false.
- localeCompare
- Think of it as asking a dictionary editor which word comes first
- Compares two strings the way a person reading that language would. It gives a negative number, 0 or a positive number, which is exactly what sorting needs. A plain sort puts every capital before every small letter instead.
- Unicode and code points
- Think of it as the master list that gives every tile in every language its own number
- Behind every character is a number from a shared world list called Unicode.
codePointAtreads that number andString.fromCodePointturns numbers back into characters. - For example The code point for
Ais 65. - Emoji and storage slots
- Think of it as an extra wide tile that takes up two slots on the rack
lengthcounts storage slots, not what a person sees. Many emoji use two slots, so a single emoji can make the length look one too high.- For example
"hi👋".lengthis 4, though you see 3 characters. - Spread (...)
- Think of it as tipping the rack out so each real tile lands separately on the table
- Three dots in front of a string pour out its real characters, one each, keeping emoji whole. Put them in square brackets and you get an array of characters you can count or reverse safely.
- For example
[..."hi👋"].lengthis 3.
Make and read
Write text in quotes or backticks, count its characters and pick out any one of them.
A string is text: a row of characters, each with a position that starts at 0. You can wrap it in single quotes, double quotes or backticks. Backticks are the handy one, because they let you drop values straight into the text with ${ }.
Picture it: positions
Ashaname.at(-1)aPositions start at 0. Negative numbers count from the end.Counts the characters. It is a property, so no brackets.
See the exampleReads the character at position i.
See the exampleLike str[i], but negative numbers count from the end.
See the exampleThe older way to read one character.
See the exampleA template literal: fills values into the text for you.
See the exampleconst single = 'Hello';
const double = "Namaste";
const name = "Asha";
const greeting = `Hi ${name}, you have ${2 + 3} messages`; // backticks fill in values
console.log(greeting);
console.log(name.length); // how many characters
console.log(name[0], name.at(-1)); // first, and last counting from the end
console.log(name.charAt(10)); // out of range gives an empty string
Easy way to remember: use backticks whenever the text has a value inside it. It is easier to read than joining pieces with +.
$ node make.js Hi Asha, you have 5 messages 4 A a
let word = "cat";
word[0] = "b"; // ignored: a string cannot be edited in place
console.log(word);
const upper = word.toUpperCase(); // every method gives you a NEW string
console.log(word, upper);
word = "b" + word.slice(1); // to "change" it, build a new one and reassign
console.log(word);
Why it matters: strings never change. Every tool in this guide gives you a new string, so remember to keep the result.
$ node immutable.js cat cat CAT bat
Search inside
Check whether some text appears, and find exactly where it is.
Checks if the text appears anywhere inside.
See the exampleChecks the very beginning.
See the exampleChecks the very end.
See the exampleFinds where the text first appears.
See the exampleFinds where the text last appears.
See the exampleconst email = "asha.k@razornext.com";
console.log(email.includes("@")); // is it anywhere inside?
console.log(email.startsWith("asha")); // at the very start?
console.log(email.endsWith(".com")); // at the very end?
console.log(email.indexOf(".")); // position of the first match
console.log(email.lastIndexOf(".")); // position of the last match
console.log(email.indexOf("#")); // -1 means not found
console.log(email.toLowerCase().includes("RAZOR".toLowerCase())); // ignore case
Watch for this: every search is case sensitive. Lower case both sides first when capitals should not matter.
$ node search.js true true true 4 16 -1 true
Cut and join
Take a piece of a string, split it into an array, and glue arrays back into text.
Picture it: split
"report-2026-09.pdf"split("-")"report""2026""09.pdf"The string becomes an array, cut at every dash.Copies the part from start up to, but not including, end. Negatives count from the end.
See the exampleLike slice, but treats negatives as 0. Prefer slice.
See the exampleCuts the string at every separator.
See the exampleThe opposite of split: glues array items into one string.
See the exampleconst file = "report-2026-09.pdf";
console.log(file.slice(0, 6)); // from 0 up to, not including, 6
console.log(file.slice(-3)); // the last 3 characters
console.log(file.slice(7, -4)); // negative numbers count from the end
const parts = file.split("-"); // cut into an array at every "-"
console.log(parts);
console.log(parts.join(" / ")); // glue an array back into one string
console.log("a,b,,c".split(",")); // empty pieces are kept
console.log([..."abc"]); // split into single characters
Easy way to remember: split turns text into an array so you can use array tools, and join turns it back.
$ node cut.js report pdf 2026-09 [ 'report', '2026', '09.pdf' ] report / 2026 / 09.pdf [ 'a', 'b', '', 'c' ] [ 'a', 'b', 'c' ]
Tidy and shape
Change the case, strip stray spaces and pad text to a fixed width.
Removes spaces, tabs and line breaks at both ends.
See the exampleRemoves them at just one end.
See the exampleMakes every letter small.
See the exampleAdds fill characters until the string is that long.
See the exampleCopies the string that many times in a row.
See the exampleconst raw = " Shree Kumar ";
console.log(`[${raw.trim()}]`); // remove spaces at both ends
console.log(`[${raw.trimStart()}]`); // only at the start
console.log(raw.trim().toUpperCase());
console.log(raw.trim().toLowerCase());
console.log("7".padStart(3, "0")); // "007": fill on the left
console.log("Total".padEnd(10, ".") + "₹450");
console.log("ab".repeat(3));
Rule of thumb: trim anything a person typed before you save or compare it. Stray spaces cause more bugs than you would think.
$ node look.js [Shree Kumar] [Shree Kumar ] SHREE KUMAR shree kumar 007 Total.....₹450 ababab
Replace parts
Swap one piece of text for another, once or everywhere.
Picture it: replaceAll
red apple, red carreplaceAll("red", "blue")blue apple, blue carEvery match is swapped, not just the first.Swaps only the first match.
See the exampleSwaps every match.
See the exampleA regular expression with g matches patterns, like every digit.
See the exampleYour helper decides what each match becomes.
See the exampleconst text = "red apple, red car, red door";
console.log(text.replace("red", "blue")); // only the first match
console.log(text.replaceAll("red", "blue")); // every match
console.log(text.replace(/red/g, "green")); // a regex with g also means every match
// the replacement can be a function of what was found
const phone = "call 98765 43210 now";
console.log(phone.replace(/\d/g, (digit, index) => (index < 11 ? "*" : digit)));
Watch for this: replace with plain text only changes the first match. Reach for replaceAll when you mean all of them.
$ node replace.js blue apple, red car, red door blue apple, blue car, blue door green apple, green car, green door call ***** 43210 now
Compare and sort
Check if two strings match and put words in the order a person expects.
| Question | Use | Notes |
|---|---|---|
| Exactly the same? | a === b | case and accents count |
| Same, ignoring case? | a.toLowerCase() === b.toLowerCase() | simple and fast |
| Same, ignoring case and accents? | localeCompare(b, undefined, { sensitivity: "base" }) | gives 0 when they match |
| Sort words nicely | list.sort((a, b) => a.localeCompare(b)) | follows language rules |
console.log("apple" === "apple"); // exact match
console.log("Apple" === "apple"); // case matters
console.log("b" > "a", "B" > "a"); // compares character codes, capitals come first
const names = ["zoya", "Aman", "émile", "Bina"];
console.log([...names].sort()); // plain sort: capitals, then small, then accents
console.log([...names].sort((a, b) => a.localeCompare(b))); // how a person would sort
const same = (a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }) === 0;
console.log(same("Resume", "résumé")); // ignores case and accents
Why it matters: plain sort() puts all capitals before small letters and accents last. localeCompare sorts the way a dictionary does.
$ node compare.js true false true false [ 'Aman', 'Bina', 'zoya', 'émile' ] [ 'Aman', 'Bina', 'émile', 'zoya' ] true
Emoji and characters
Count real characters safely when text has emoji, and work with the numbers behind letters.
Builds a string from those numbers.
See the exampleconst word = "hi👋";
console.log(word.length); // 4, because the emoji takes two slots
console.log([...word].length); // 3: spread counts real characters
console.log([...word].reverse().join("")); // safe reverse
console.log("A".codePointAt(0)); // the number behind a character
console.log(String.fromCodePoint(65, 66, 128578));
const multi = `line one
line two`; // backticks keep line breaks
console.log(multi.split("\n").length);
Watch for this: length counts storage slots, not characters. Many emoji take two, so use [...str].length when you show a character count to people.
$ node chars.js 4 3 👋ih 65 AB🙂 2
All together
Clean up a sign up form: fix the name, tidy the email, make a handle and hide the phone number.
Real forms are messy. People type extra spaces, random capitals and full numbers you should not show back. Each helper below is one line, built from tools in the earlier modules.
// clean up what a person typed into a sign up form
const form = { name: " sHREE kumar sharma ", email: " Shree.S@Mail.com ", phone: "9876543210" };
// 1. title case: trim, split into words, capitalise the first letter of each
const titleCase = (s) =>
s.trim().toLowerCase().split(/\s+/).map((w) => w[0].toUpperCase() + w.slice(1)).join(" ");
// 2. a short handle from the name
const handle = (s) => "@" + titleCase(s).split(" ").map((w) => w.slice(0, 3)).join("").toLowerCase();
// 3. hide most of the phone number
const mask = (p) => p.slice(-4).padStart(p.length, "•");
const clean = {
name: titleCase(form.name),
email: form.email.trim().toLowerCase(),
handle: handle(form.name),
phone: mask(form.phone),
};
console.log(clean.handle, clean.phone);
console.log(`${clean.name} <${clean.email}> joined as ${clean.handle}`);
What each part uses: trim and case from module 04, split and join from 03, slice from 03 again, and padStart from 04 to mask the phone.
$ node profile.js @shrkumsha ••••••3210 Shree Kumar Sharma <shree.s@mail.com> joined as @shrkumsha
# save any example as a file and run it with Node 22 $ node profile.js # or paste it into your browser console with F12
Which one do I need?
Start from what you want to do, then read across to the tool and what it gives back.
| I want to | Use | You get |
|---|---|---|
| Count characters | str.length | a number |
| Read the last character | str.at(-1) | one character |
| Check it contains text | str.includes(x) | true or false |
| Find where text is | str.indexOf(x) | a position or -1 |
| Take a piece | str.slice(a, b) | a new string |
| Cut into an array | str.split(",") | an array |
| Remove outer spaces | str.trim() | a new string |
| Change case | toUpperCase / toLowerCase | a new string |
| Add leading zeros | str.padStart(3, "0") | a new string |
| Swap every match | str.replaceAll(a, b) | a new string |
| Sort words nicely | a.localeCompare(b) | a negative, 0 or positive number |
| Count emoji safely | [...str].length | a number |
| Fill in values | `Hi ${name}` | a new string |