Welcome back! š In the previous lesson, you mastered arrow functions. Now we're kicking off the Working with Data Structures section with the most fundamental data type you'll work with every day ā Strings!
Strings are everywhere ā usernames, messages, URLs, form inputs, API responses, file paths, and more. JavaScript comes packed with powerful built-in string methods that let you search, transform, extract, and format text with ease.
By the end of this lesson, you'll never struggle with string manipulation again. Let's dive in!
What is a String?
A string is a sequence of characters used to represent text. In JavaScript, strings are primitive values ā but they come with a rich set of built-in methods you can call on them.
let name = "Mihir"; // double quotes
let city = 'Mumbai'; // single quotes
let message = `Hello, World!`; // template literal (backticks)All three are valid strings in JavaScript. We'll cover template literals in depth in the next lesson.
String Basics
String Length
let name = "JavaScript";
console.log(name.length); // 10Accessing Characters
Strings are zero-indexed ā the first character is at index 0.
let lang = "JavaScript";
console.log(lang[0]); // "J"
console.log(lang[4]); // "S"
console.log(lang[lang.length - 1]); // "t" (last character)Strings are Immutable
You can read characters but you cannot change them directly.
let name = "Mihir";
name[0] = "P"; // ā Does nothing ā strings are immutable
console.log(name); // "Mihir" ā unchanged
// ā
Create a new string instead
let newName = "P" + name.slice(1);
console.log(newName); // "Pihir"String Concatenation
Using + Operator
let firstName = "Mihir";
let lastName = "Shah";
let fullName = firstName + " " + lastName;
console.log(fullName); // "Mihir Shah"Using Template Literals (Recommended ā )
let firstName = "Mihir";
let lastName = "Shah";
let fullName = `${firstName} ${lastName}`;
console.log(fullName); // "Mihir Shah"We'll go deeper on template literals in the next lesson ā but always prefer them over + for readability.
Case Methods
toUpperCase() and toLowerCase()
let text = "Hello, JavaScript!";
console.log(text.toUpperCase()); // "HELLO, JAVASCRIPT!"
console.log(text.toLowerCase()); // "hello, javascript!"Real-World Use ā Case-Insensitive Comparison
let userInput = "JAVASCRIPT";
let expected = "javascript";
// ā Case-sensitive ā fails
console.log(userInput === expected); // false
// ā
Normalize both to lowercase before comparing
console.log(userInput.toLowerCase() === expected.toLowerCase()); // trueSearching Methods
includes() ā Does the string contain a value?
Returns true or false.
let sentence = "JavaScript is awesome!";
console.log(sentence.includes("JavaScript")); // true
console.log(sentence.includes("Python")); // false
console.log(sentence.includes("is")); // truestartsWith() and endsWith()
let url = "https://www.example.com";
console.log(url.startsWith("https")); // true
console.log(url.startsWith("http://"));// false
console.log(url.endsWith(".com")); // true
console.log(url.endsWith(".org")); // falseindexOf() ā Find the position of a substring
Returns the index of the first occurrence, or -1 if not found.
let text = "Hello, JavaScript! JavaScript is great.";
console.log(text.indexOf("JavaScript")); // 7
console.log(text.indexOf("Python")); // -1
console.log(text.indexOf("JavaScript", 10)); // 19 (search from index 10)lastIndexOf() ā Find the last occurrence
let text = "Hello, JavaScript! JavaScript is great.";
console.log(text.lastIndexOf("JavaScript")); // 19 (last occurrence)Practical ā Check if URL is Secure
function isSecureUrl(url) {
return url.startsWith("https://");
}
console.log(isSecureUrl("https://example.com")); // true
console.log(isSecureUrl("http://example.com")); // falseExtracting Methods
slice(start, end) ā Extract a portion
Returns characters from start up to (but not including) end. Accepts negative indexes.
let text = "JavaScript";
// 0123456789
console.log(text.slice(0, 4)); // "Java"
console.log(text.slice(4)); // "Script" (to end)
console.log(text.slice(-6)); // "Script" (6 from end)
console.log(text.slice(0, -6)); // "Java" (all except last 6)substring(start, end) ā Similar to slice
Like slice but does not support negative indexes.
let text = "JavaScript";
console.log(text.substring(0, 4)); // "Java"
console.log(text.substring(4)); // "Script"slice vs substring
let text = "JavaScript";
// Negative index ā slice supports it, substring does not
console.log(text.slice(-6)); // "Script" ā
console.log(text.substring(-6)); // "JavaScript" ā treats negative as 0
// ā
Prefer slice ā it handles negative indexes correctlycharAt(index) ā Get character at a position
let text = "Hello";
console.log(text.charAt(0)); // "H"
console.log(text.charAt(4)); // "o"
console.log(text[0]); // "H" ā same result using bracket notationModifying Methods
replace() ā Replace first occurrence
let text = "I love JavaScript. JavaScript is great!";
console.log(text.replace("JavaScript", "Python"));
// "I love Python. JavaScript is great!" ā only first replacedreplaceAll() ā Replace all occurrences
let text = "I love JavaScript. JavaScript is great!";
console.log(text.replaceAll("JavaScript", "Python"));
// "I love Python. Python is great!" ā
trim(), trimStart(), trimEnd() ā Remove whitespace
let messy = " Hello, World! ";
console.log(messy.trim()); // "Hello, World!"
console.log(messy.trimStart()); // "Hello, World! "
console.log(messy.trimEnd()); // " Hello, World!"Real-World Use ā Clean User Input
function cleanInput(input) {
return input.trim().toLowerCase();
}
console.log(cleanInput(" MIHIR ")); // "mihir"
console.log(cleanInput(" JavaScript ")); // "javascript"repeat() ā Repeat a string
let dash = "-".repeat(20);
let stars = "ā".repeat(5);
console.log(dash); // "--------------------"
console.log(stars); // "āāāāā"Padding Methods
padStart(length, padString) ā Pad from the left
let num = "42";
console.log(num.padStart(5, "0")); // "00042"
console.log(num.padStart(5, "*")); // "***42"padEnd(length, padString) ā Pad from the right
let label = "Name";
console.log(label.padEnd(10, ".")); // "Name......"Real-World Use ā Format a Receipt
let items = [
{ name: "Laptop", price: 55000 },
{ name: "Mouse", price: 800 },
{ name: "Bag", price: 1200 },
];
console.log("=".repeat(30));
for (let item of items) {
console.log(item.name.padEnd(15) + `ā¹${item.price}`.padStart(10));
}
console.log("=".repeat(30));
// Output:
// ==============================
// Laptop ā¹55000
// Mouse ā¹800
// Bag ā¹1200
// ==============================Splitting and Joining
split(separator) ā String to Array
Splits a string into an array of substrings.
let csv = "Mihir,Priya,Rahul,Sara";
let names = csv.split(",");
console.log(names); // ["Mihir", "Priya", "Rahul", "Sara"]
console.log(names.length); // 4// Split into individual characters
let word = "Hello";
let chars = word.split("");
console.log(chars); // ["H", "e", "l", "l", "o"]
// Split into words
let sentence = "JavaScript is awesome";
let words = sentence.split(" ");
console.log(words); // ["JavaScript", "is", "awesome"]join() ā Array to String (opposite of split)
let words = ["JavaScript", "is", "awesome"];
console.log(words.join(" ")); // "JavaScript is awesome"
console.log(words.join("-")); // "JavaScript-is-awesome"
console.log(words.join("")); // "JavaScriptisawesome"Real-World Use ā Slugify a Title
function slugify(title) {
return title
.toLowerCase()
.trim()
.split(" ")
.join("-");
}
console.log(slugify("Hello World")); // "hello-world"
console.log(slugify(" JavaScript Is Amazing ")); // "javascript-is-amazing"
console.log(slugify("Working With Data Structures")); // "working-with-data-structures"Real-World Examples
Example 1: Username Validator
function validateUsername(username) {
let cleaned = username.trim();
if (cleaned.length < 3) {
return "ā Username too short (min 3 characters)";
}
if (cleaned.length > 20) {
return "ā Username too long (max 20 characters)";
}
if (cleaned.includes(" ")) {
return "ā Username cannot contain spaces";
}
return `ā
Valid username: "${cleaned}"`;
}
console.log(validateUsername(" mi ")); // ā too short
console.log(validateUsername("Mihir Shah")); // ā contains space
console.log(validateUsername("mihir_dev_2024")); // ā
validExample 2: Format a Phone Number
function formatPhone(raw) {
let digits = raw.trim().replace(/\D/g, ""); // keep digits only
if (digits.length !== 10) {
return "ā Invalid phone number";
}
return `+91 ${digits.slice(0, 5)}-${digits.slice(5)}`;
}
console.log(formatPhone("9876543210")); // +91 98765-43210
console.log(formatPhone(" 98765 43210 ")); // +91 98765-43210
console.log(formatPhone("123")); // ā Invalid phone numberExample 3: Truncate Long Text
function truncate(text, maxLength, suffix = "...") {
if (text.length <= maxLength) return text;
return text.slice(0, maxLength - suffix.length).trimEnd() + suffix;
}
let title = "Working with Data Structures in JavaScript";
console.log(truncate(title, 20)); // "Working with Data..."
console.log(truncate(title, 30)); // "Working with Data Structure..."
console.log(truncate(title, 100)); // Full title ā no truncationExample 4: Parse a CSV Line
function parseCSV(line) {
let fields = line.split(",").map(field => field.trim());
return {
name: fields[0],
email: fields[1],
role: fields[2],
city: fields[3],
};
}
let row = " Mihir Shah , mihir@example.com , Admin , Mumbai ";
let user = parseCSV(row);
console.log(user);
// { name: 'Mihir Shah', email: 'mihir@example.com', role: 'Admin', city: 'Mumbai' }Example 5: Capitalize Each Word
function titleCase(sentence) {
return sentence
.toLowerCase()
.split(" ")
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}
console.log(titleCase("hello world")); // "Hello World"
console.log(titleCase("working with data structures")); // "Working With Data Structures"
console.log(titleCase("jAVAsCRIPT iS aWESOME")); // "Javascript Is Awesome"String Methods Cheat Sheet
| Method | What it does | Example |
|---|---|---|
length | Number of characters | "Hello".length ā 5 |
toUpperCase() | All uppercase | "hi".toUpperCase() ā "HI" |
toLowerCase() | All lowercase | "HI".toLowerCase() ā "hi" |
includes(str) | Contains a substring? | "Hello".includes("ell") ā true |
startsWith(str) | Starts with? | "Hello".startsWith("He") ā true |
endsWith(str) | Ends with? | "Hello".endsWith("lo") ā true |
indexOf(str) | First index of | "Hello".indexOf("l") ā 2 |
lastIndexOf(str) | Last index of | "Hello".lastIndexOf("l") ā 3 |
slice(s, e) | Extract part | "Hello".slice(1, 3) ā "el" |
replace(a, b) | Replace first | "Hi Hi".replace("Hi","Hey") ā "Hey Hi" |
replaceAll(a, b) | Replace all | "Hi Hi".replaceAll("Hi","Hey") ā "Hey Hey" |
trim() | Remove whitespace both ends | " Hi ".trim() ā "Hi" |
split(sep) | String to array | "a,b".split(",") ā ["a","b"] |
repeat(n) | Repeat string | "ab".repeat(3) ā "ababab" |
padStart(n, c) | Pad left | "5".padStart(3,"0") ā "005" |
padEnd(n, c) | Pad right | "5".padEnd(3,"0") ā "500" |
charAt(i) | Char at index | "Hello".charAt(1) ā "e" |
Common Mistakes
Mistake 1: Using == to Compare Strings
// ā Loose equality ā unexpected results
console.log("5" == 5); // true (type coercion!)
// ā
Always use === for strings
console.log("5" === 5); // false ā
console.log("hi" === "hi"); // true ā
Mistake 2: Forgetting trim() on User Input
let input = " mihir ";
// ā Spaces cause false negatives
console.log(input === "mihir"); // false ā
// ā
Always trim user input before comparison
console.log(input.trim() === "mihir"); // true ā
Mistake 3: replace() Only Replaces the First Match
let text = "cat and cat and cat";
// ā Only replaces first "cat"
console.log(text.replace("cat", "dog")); // "dog and cat and cat"
// ā
Use replaceAll() for all occurrences
console.log(text.replaceAll("cat", "dog")); // "dog and dog and dog" ā
Mistake 4: Mutating a String Directly
let name = "mihir";
// ā Strings are immutable ā this does nothing
name[0] = "M";
console.log(name); // "mihir" ā unchanged!
// ā
Create a new string
name = name[0].toUpperCase() + name.slice(1);
console.log(name); // "Mihir" ā
Practical Exercise
Create a file called strings.js:
// šÆ Strings Practice
// 1. String analyzer
function analyzeString(str) {
console.log(`\n=== Analyzing: "${str}" ===`);
console.log(`Length: ${str.length}`);
console.log(`Uppercase: ${str.toUpperCase()}`);
console.log(`Lowercase: ${str.toLowerCase()}`);
console.log(`Reversed: ${str.split("").reverse().join("")}`);
console.log(`Word count: ${str.trim().split(" ").filter(w => w).length}`);
console.log(`Has spaces: ${str.includes(" ")}`);
console.log(`First char: ${str[0]}`);
console.log(`Last char: ${str[str.length - 1]}`);
}
analyzeString("Hello World");
analyzeString("JavaScript");
analyzeString(" Working with Strings ");
// 2. Email validator
function validateEmail(email) {
let cleaned = email.trim().toLowerCase();
let hasAt = cleaned.includes("@");
let hasDot = cleaned.includes(".");
let atIndex = cleaned.indexOf("@");
let dotAfterAt = cleaned.lastIndexOf(".") > atIndex;
if (hasAt && hasDot && dotAfterAt && atIndex > 0) {
return `ā
Valid email: ${cleaned}`;
}
return `ā Invalid email: "${email}"`;
}
console.log("\n=== Email Validator ===");
console.log(validateEmail("mihir@example.com"));
console.log(validateEmail("not-an-email"));
console.log(validateEmail("missing@dot"));
console.log(validateEmail(" MIHIR@EXAMPLE.COM "));
// 3. Password strength checker
function checkPassword(password) {
console.log(`\nPassword: "${password}"`);
let hasUpper = password !== password.toLowerCase();
let hasLower = password !== password.toUpperCase();
let hasDigit = "0123456789".split("").some(d => password.includes(d));
let longEnough = password.length >= 8;
let strength = [hasUpper, hasLower, hasDigit, longEnough]
.filter(Boolean).length;
let label = strength === 4 ? "šŖ Strong"
: strength === 3 ? "š” Medium"
: "š“ Weak";
console.log(` Uppercase: ${hasUpper ? "ā
" : "ā"}`);
console.log(` Lowercase: ${hasLower ? "ā
" : "ā"}`);
console.log(` Digit: ${hasDigit ? "ā
" : "ā"}`);
console.log(` Length 8+: ${longEnough ? "ā
" : "ā"}`);
console.log(` Strength: ${label}`);
}
console.log("\n=== Password Checker ===");
checkPassword("abc");
checkPassword("password");
checkPassword("Pass1234");
// 4. Format product tags
function formatTags(tagString) {
return tagString
.split(",")
.map(tag => tag.trim().toLowerCase().replaceAll(" ", "-"))
.filter(tag => tag.length > 0)
.join(" | ");
}
console.log("\n=== Tag Formatter ===");
console.log(formatTags("JavaScript, Web Dev, Front End, ES6"));
// javascript | web-dev | front-end | es6Run it:
node strings.jsExpected Output:
=== Analyzing: "Hello World" ===
Length: 11
Uppercase: HELLO WORLD
Lowercase: hello world
Reversed: dlroW olleH
Word count: 2
Has spaces: true
First char: H
Last char: d
=== Email Validator ===
ā
Valid email: mihir@example.com
ā Invalid email: "not-an-email"
ā Invalid email: "missing@dot"
ā
Valid email: mihir@example.com
=== Password Checker ===
Password: "Pass1234"
Uppercase: ā
Lowercase: ā
Digit: ā
Length 8+: ā
Strength: šŖ Strong
=== Tag Formatter ===
javascript | web-dev | front-end | es6Key Takeaways
Congratulations! š You now have a complete toolkit for working with strings in JavaScript.
ā Strings are immutable ā methods always return a new string, they never change the original.
ā
Case methods: toUpperCase(), toLowerCase() ā always normalize case before comparing.
ā
Searching: includes(), startsWith(), endsWith(), indexOf(), lastIndexOf().
ā
Extracting: slice(start, end) ā supports negative indexes, preferred over substring().
ā
Modifying: replace() replaces first match only ā use replaceAll() for all occurrences.
ā
Whitespace: Always trim() user input before processing or comparing.
ā
Splitting: split(sep) ā array. join(sep) ā string. Used together constantly.
ā
Padding: padStart() and padEnd() for formatting numbers and table-style output.
Best Practices
- ā
Always
trim()user input before validating or storing - ā
Use
toLowerCase()ortoUpperCase()before comparing strings - ā
Prefer
slice()oversubstring()ā it handles negative indexes correctly - ā
Use
replaceAll()when you want to replace every occurrence, not just the first - ā
Prefer template literals over
+concatenation for readability - ā
Use
split()+map()+join()for powerful string transformations - ā Remember ā strings are immutable ā always assign the result to a variable
- ā
Use
includes()instead ofindexOf() !== -1ā it reads more naturally
What's Next?
Great work! š You now have a complete string manipulation toolkit.
Next up, let's explore Template Literals ā ā the modern, powerful way to work with strings in JavaScript. Multi-line strings, embedded expressions, tagged templates and more!
Let's keep going! šŖ