Working with text
Names, addresses, messages, anything typed into a form — most of what a web page handles is text. JavaScript calls a piece of text a string, and gives you a large set of tools for taking it apart and putting it back together.
let city = "Karachi";
console.log(city);
console.log(city.length);
Karachi 7
length counts the characters. Note there are no brackets after it — it is a
property, a fact about the string, not something the string does. Everything
else in this lesson has brackets.
Quotes, and the apostrophe problem
Single and double quotes work identically. What matters is that you close with the same one you opened, and that the text inside does not contain that character.
console.log("Ayesha's canteen");
console.log('She said "hello" quietly.');
console.log('Ayesha\'s canteen');
Ayesha's canteen She said "hello" quietly. Ayesha's canteen
The first line uses double quotes so the apostrophe is just a character. The second flips it. The third uses a backslash to escape the quote, telling JavaScript that this one is text rather than the end of the string.
The habit worth forming: pick the quote that avoids escaping. Reaching for the backslash is a sign you chose the other one.
A few other escapes appear often: \n is a newline, \t a tab, and \\ a
literal backslash.
console.log("Line one\nLine two");
Line one Line two
Template literals
Gluing strings together with + works and reads badly:
let name = "Fatima";
let cups = 3;
console.log("Hello " + name + ", you ordered " + cups + " cups.");
Hello Fatima, you ordered 3 cups.
Count the quotes and pluses in that line and you will see why it goes wrong so often — one missing space inside the quotes and the sentence runs together.
Template literals use backticks instead, and let you drop values straight
in with ${...}:
let name = "Fatima";
let cups = 3;
console.log(`Hello ${name}, you ordered ${cups} cups.`);
Hello Fatima, you ordered 3 cups.
The spaces are exactly where you typed them, because they are part of the text rather than something you had to remember to add.
Anything can go inside ${}, including a calculation or a ternary:
let price = 250;
let qty = 3;
console.log(`Total: ${price * qty} rupees`);
Total: 750 rupees
Backticks also let a string span several lines without \n:
let receipt = `Chai Corner
Total: 750
Thank you`;
console.log(receipt);
Chai Corner Total: 750 Thank you
Use template literals by default. The + form is worth recognising in old
code and not worth writing.
Strings are immutable
This is the rule that explains every surprise in the rest of the lesson.
A string can never be changed. Every method that looks like it edits a string actually builds a new one and hands it back, leaving the original exactly as it was.
let greeting = "hello";
greeting.toUpperCase();
console.log(greeting);
console.log(greeting.toUpperCase());
hello HELLO
The second line did the work and threw the result away. Nothing was assigned, so nothing changed. This is the single most common source of "why is my string method not working" — the method worked perfectly, and the answer went nowhere.
To keep the result, store it:
let greeting = "hello";
let loud = greeting.toUpperCase();
console.log(greeting);
console.log(loud);
hello HELLO
Or reassign, if you genuinely want to replace the value:
let greeting = "hello";
greeting = greeting.toUpperCase();
console.log(greeting);
HELLO
Keep this rule in mind for every method below. They all return; none of them edit.
Case, and why you lowercase before comparing
let typed = " Ayesha ";
console.log(typed.toUpperCase());
console.log(typed.toLowerCase());
console.log(typed.trim());
console.log(typed.trim().length);
console.log(typed.length);
AYESHA ayesha Ayesha 6 10
trim removes whitespace from both ends — not the middle. It is the first
thing to do with anything a person typed, because trailing spaces are
invisible and break comparisons.
Notice typed.trim().length: methods chain, because each one returns a string
that the next can work on.
Comparing names is the usual reason to change case, since
the equality lesson showed that "a"
and "A" are different values:
let entered = " KARACHI ";
let stored = "Karachi";
console.log(entered === stored);
console.log(entered.trim().toLowerCase() === stored.toLowerCase());
false true
Reaching into a string
let city = "Hyderabad";
console.log(city[0]);
console.log(city[city.length - 1]);
console.log(city.slice(0, 5));
console.log(city.slice(5));
console.log(city.slice(-4));
H d Hyder abad abad
Positions start at 0, so the first character is [0] and the last is
[length - 1]. Forgetting the - 1 gives undefined, because you asked for a
position one past the end.
slice(start, end) takes a piece. The start is included and the end is not,
which is why slice(0, 5) gives five characters. A negative number counts
back from the end.
Searching
let order = "2 chai, 1 paratha, 3 samosa";
console.log(order.includes("paratha"));
console.log(order.includes("Paratha"));
console.log(order.indexOf("paratha"));
console.log(order.indexOf("biryani"));
console.log(order.startsWith("2"));
console.log(order.endsWith("samosa"));
true false 10 -1 true true
includes answers yes or no. indexOf gives the position, or -1 when it
is not there — a historical quirk, since -1 is a real position everywhere else.
includes is clearer whenever you only need the yes-or-no.
All of these are case-sensitive, which is why "Paratha" returns false.
Lowercase both sides first when the case should not matter.
Replacing
let line = "chai, chai, paratha";
console.log(line.replace("chai", "tea"));
console.log(line.replaceAll("chai", "tea"));
console.log(line);
tea, chai, paratha tea, tea, paratha chai, chai, paratha
replace changes the first match only. replaceAll changes every one.
The third line proves the point about immutability: the original is untouched.
split and join
split turns a string into an array by cutting at a separator. join does
the reverse.
let csv = "chai,paratha,samosa";
let items = csv.split(",");
console.log(items);
console.log(items.length);
console.log(items.join(" and "));
[ 'chai', 'paratha', 'samosa' ] 3 chai and paratha and samosa
Splitting on an empty string gives every character, which is the usual way to reverse text:
let word = "chai";
console.log(word.split(""));
console.log(word.split("").reverse().join(""));
[ 'c', 'h', 'a', 'i' ] iahc
Arrays get their own lesson; for now, split and join are the bridge
between text and lists.
Padding numbers into text
let minutes = 7;
console.log(String(minutes).padStart(2, "0"));
console.log("9:" + String(minutes).padStart(2, "0"));
07 9:07
padStart is how clocks, invoice numbers and reference codes get their leading
zeros. It is a string method, so the number has to become a string first —
String(minutes) does that explicitly.
Numbers hiding as strings
The trap from the data types lesson is worth repeating here, because string methods are where it usually surfaces:
let a = "5";
let b = "3";
console.log(a + b);
console.log(Number(a) + Number(b));
53 8
+ between two strings glues. If either side is a string, you get text. Any
value that arrives from a form, a URL or a JSON file is a string until you
convert it, and the numbers lesson covers how.
The methods worth remembering
length, trim, toLowerCase, includes, slice, split, join,
replaceAll, and template literals for building output. That set covers the
overwhelming majority of everyday text work, and every one of them returns
something new rather than changing what you gave it.
Prefer learning with a teacher?
WasiLearn Academy runs small-group classes covering this material, online and in Karachi.
See the classes