⏱ Estimated Time: 10-14 hours
HTML gives you structure. CSS gives you style. JavaScript gives you behavior.
JavaScript makes web pages interactive. It responds to clicks, validates forms, updates content without refreshing, and powers everything from simple animations to complex applications.
This is where you become a programmer.
The best way to learn programming is by writing programs. This module has explanations, but the real learning happens when you write the code yourself.
For every concept:
- Read the explanation
- Type the examples yourself (don't copy-paste)
- Experiment—change things and see what happens
- Complete the exercises
When you get stuck, that's not failure. That's learning. Work through it.
Before we embark on our JavaScript journey, make sure you have the following tools:
- Text Editor: Think of it as your coding canvas. VS Code (which you set up in Module 2).
- Web Browser: Your window into the web. Chrome, Firefox, or Edge will be your stage.
- Open any web page
- Right-click → Inspect (or F12)
- Click the "Console" tab
- Type JavaScript and press Enter
Try it:
console.log("Hello, World!");<!DOCTYPE html>
<html>
<head>
<title>My First JavaScript Code</title>
</head>
<body>
<h1>Check the console</h1>
<button onclick="showMessage()">Click me</button>
<p id="message"></p>
<script>
function showMessage() {
document.getElementById("message").innerHTML = "Hello, World!";
}
console.log("Hello from the script!");
</script>
</body>
</html><body>
<h1>My Page</h1>
<script src="script.js"></script>
</body>Put the <script> tag at the end of <body> so HTML loads first.
You can also keep your JavaScript code in separate files and link them to your HTML using the <script> tag. This keeps your code organized and easy to manage.
Variables store values so you can use them later.
let name = "Jerome";
let age = 30;
let isVeteran = true;let — Value can change:
let score = 0;
score = 10; // OK
score = score + 5; // OKconst — Value cannot be reassigned:
const PI = 3.14159;
PI = 3; // ERROR!var — Old way (avoid in modern code):
var name = "John";Use const by default. Use let when you need to reassign.
- Must start with a letter,
_, or$ - Can contain letters, numbers,
_,$ - Case sensitive (
nameandNameare different) - Use camelCase:
firstName,isLoggedIn,totalAmount
// String — text
let greeting = "Hello";
let name = 'Jerome';
let message = `Welcome, ${name}!`; // Template literal
// Number — integers and decimals
let count = 42;
let price = 19.99;
let age = 25;
const pi = 3.14;
// Boolean — true or false
let isActive = true;
let hasAccount = false;
// Undefined — declared but no value
let something;
console.log(something); // undefined
// Null — intentionally empty
let empty = null;typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" (this is a JavaScript quirk)let a = 10;
let b = 3;
let x = 5;
let y = 10;
a + b // 13 — Addition
a - b // 7 — Subtraction
a * b // 30 — Multiplication
a / b // 3.333... — Division
a % b // 1 — Remainder (modulo)
a ** b // 1000 — Exponent
let sum = x + y; // 15
let difference = y - x; // 5
let product = x * y; // 50
let quotient = y / x; // 2let x = 10;
x += 5; // x = x + 5 → 15
x -= 3; // x = x - 3 → 12
x *= 2; // x = x * 2 → 24
x /= 4; // x = x / 4 → 6
x++; // x = x + 1 → 7
x--; // x = x - 1 → 65 == "5" // true — Equal (loose, converts types)
5 === "5" // false — Strict equal (no conversion)
5 != "5" // false — Not equal (loose)
5 !== "5" // true — Strict not equal
10 > 5 // true
10 < 5 // false
10 >= 10 // true
10 <= 9 // falseAlways use === and !== to avoid type conversion surprises.
true && true // true — AND (both must be true)
true && false // false
true || false // true — OR (one must be true)
false || false // false
!true // false — NOT (flips the value)
!false // truelet single = 'Hello';
let double = "World";
let template = `Hello, ${name}!`; // Can include variables
let greeting = "Hello, world!";
let name = "Alice";let text = "Hello, World!";
let message = "Hello, world!";
text.length // 13
text.toUpperCase() // "HELLO, WORLD!"
text.toLowerCase() // "hello, world!"
text.indexOf("World") // 7 (position where "World" starts)
text.includes("Hello") // true
text.startsWith("Hello") // true
text.endsWith("!") // true
text.slice(0, 5) // "Hello" (from index 0 to 4)
text.slice(7) // "World!" (from index 7 to end)
text.replace("World", "JavaScript") // "Hello, JavaScript!"
text.split(", ") // ["Hello", "World!"]
text.trim() // Removes whitespace from ends
message.length // 13
message.toUpperCase() // "HELLO, WORLD!"
message.indexOf("world") // 7let name = "Jerome";
let age = 30;
// Old way (concatenation)
let message = "Hello, " + name + "! You are " + age + " years old.";
// New way (template literals)
let message = `Hello, ${name}! You are ${age} years old.`;
// Multi-line strings
let html = `
<div class="card">
<h2>${name}</h2>
<p>Age: ${age}</p>
</div>
`;let age = 20;
let score = 85;
if (age >= 21) {
console.log("You can enter.");
} else if (age >= 18) {
console.log("You can enter but cannot drink.");
} else {
console.log("You cannot enter.");
}
if (score >= 90) {
console.log("A Grade");
} else if (score >= 80) {
console.log("B Grade");
} else {
console.log("C or Lower");
}Short form for simple if/else:
let status = age >= 18 ? "adult" : "minor";let day = "Monday";
switch (day) {
case "Monday":
console.log("Start of the week");
break;
case "Friday":
console.log("Almost weekend!");
break;
case "Saturday":
case "Sunday":
console.log("Weekend!");
break;
default:
console.log("Regular day");
}Don't forget break or execution falls through to the next case.
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
console.log("Count: " + i);
}Parts: for (initialization; condition; update)
let count = 0;
while (count < 5) {
console.log(count);
count++;
}
let count = 0;
while (count < 3) {
console.log("Looping...");
count++;
}Iterates over array elements:
let colors = ["red", "green", "blue"];
for (let color of colors) {
console.log(color); // red, green, blue
}Iterates over object keys:
let person = { name: "Jerome", age: 30 };
for (let key in person) {
console.log(key, person[key]); // name Jerome, age 30
}// break — exit the loop entirely
for (let i = 0; i < 10; i++) {
if (i === 5) break;
console.log(i); // 0, 1, 2, 3, 4
}
// continue — skip to next iteration
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
console.log(i); // 0, 1, 3, 4
}Functions are reusable blocks of code.
function greet(name) {
return `Hello, ${name}!`;
}
let message = greet("Jerome"); // "Hello, Jerome!"
function greet(name) {
console.log("Hello, " + name + "!");
}
greet("Alice");const greet = function(name) {
return `Hello, ${name}!`;
};Modern, shorter syntax:
const greet = (name) => {
return `Hello, ${name}!`;
};
// Even shorter for single expressions
const greet = name => `Hello, ${name}!`;
// Multiple parameters need parentheses
const add = (a, b) => a + b;
// No parameters need empty parentheses
const sayHello = () => "Hello!";function introduce(name, age = 25) { // age has a default value
return `I'm ${name}, ${age} years old.`;
}
introduce("Jerome", 30); // "I'm Jerome, 30 years old."
introduce("Sarah"); // "I'm Sarah, 25 years old."Functions return undefined by default. Use return to send a value back:
function square(n) {
return n * n;
}
let result = square(4); // 16Arrays store ordered lists of values.
let fruits = ["apple", "banana", "cherry"];
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, "two", true, null];
let empty = [];let fruits = ["apple", "banana", "cherry"];
let numbers = [1, 2, 3, 4, 5];
fruits[0] // "apple" (first element)
fruits[1] // "banana"
fruits[2] // "cherry"
fruits.length // 3
fruits[fruits.length - 1] // "cherry" (last element)
numbers[2]; // Access the third element (3)
numbers.length; // 5let fruits = ["apple", "banana"];
fruits.push("cherry"); // Add to end → ["apple", "banana", "cherry"]
fruits.pop(); // Remove from end → ["apple", "banana"]
fruits.unshift("mango"); // Add to start → ["mango", "apple", "banana"]
fruits.shift(); // Remove from start → ["apple", "banana"]
fruits[1] = "grape"; // Replace element → ["apple", "grape"]let numbers = [1, 2, 3, 4, 5];
// find — first element matching condition
numbers.find(n => n > 3); // 4
// findIndex — index of first match
numbers.findIndex(n => n > 3); // 3
// includes — check if exists
numbers.includes(3); // true
// indexOf — position of element
numbers.indexOf(3); // 2
// join — combine into string
numbers.join("-"); // "1-2-3-4-5"
numbers.join(", "); // "5, 4, 3, 2, 1"
// slice — copy portion (doesn't modify original)
numbers.slice(1, 4); // [2, 3, 4]
// splice — remove/insert elements (modifies original)
numbers.splice(2, 1); // Removes 1 element at index 2
// concat — combine arrays
[1, 2].concat([3, 4]); // [1, 2, 3, 4]
// reverse — reverse order (modifies original)
numbers.reverse(); // [5, 4, 3, 2, 1]
// sort — sort elements (modifies original)
numbers.sort((a, b) => a - b); // Ascending
numbers.sort((a, b) => b - a); // DescendingThese are essential. Master them.
Execute a function for each element:
let fruits = ["apple", "banana", "cherry"];
fruits.forEach(fruit => {
console.log(fruit);
});
// apple
// banana
// cherryTransform each element, return new array:
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]
let names = ["jerome", "sarah", "mike"];
let capitalized = names.map(name => name.toUpperCase());
// ["JEROME", "SARAH", "MIKE"]Keep elements that pass a test:
let numbers = [1, 2, 3, 4, 5, 6];
let evens = numbers.filter(n => n % 2 === 0);
// [2, 4, 6]
let people = [
{ name: "Jerome", age: 30 },
{ name: "Sarah", age: 17 },
{ name: "Mike", age: 25 }
];
let adults = people.filter(person => person.age >= 18);
// [{ name: "Jerome", age: 30 }, { name: "Mike", age: 25 }]Combine all elements into one value:
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((total, n) => total + n, 0);
// 15
// Breakdown:
// (0, 1) => 1
// (1, 2) => 3
// (3, 3) => 6
// (6, 4) => 10
// (10, 5) => 15let products = [
{ name: "Laptop", price: 1000, inStock: true },
{ name: "Phone", price: 500, inStock: false },
{ name: "Tablet", price: 300, inStock: true }
];
let result = products
.filter(p => p.inStock)
.map(p => p.name)
.join(", ");
// "Laptop, Tablet"Objects store key-value pairs.
let person = {
name: "Jerome",
age: 30,
isVeteran: true,
skills: ["JavaScript", "HTML", "CSS"]
};
// Create the object
const person = {
name: "Jody",
age: 30,
gender: "male",
sayHello: function () {
console.log("Hello!");
},
};// Dot notation
person.name // "Jerome"
person.age // 30
// Bracket notation (required for dynamic keys)
person["name"] // "Jerome"
let key = "age";
person[key] // 30
// Accessing the object
console.log(person.name); // Output: Jody
console.log(person["age"]); // Output: 30
person.sayHello(); // Output: Hello!// Add/update properties
person.email = "jerome@example.com";
person.age = 31;
// Delete properties
delete person.email;
// Adding to or updating the object
person.age = 35;
person.job = "developer";
console.log(person.age); // Output: 35
console.log(person.job); // Output: developer
// Removing properties
delete person.gender;
console.log(person.gender); // Output: undefinedlet person = { name: "Jerome", age: 30 };
Object.keys(person) // ["name", "age"]
Object.values(person) // ["Jerome", 30]
Object.entries(person) // [["name", "Jerome"], ["age", 30]]Objects can contain functions:
let calculator = {
add: function(a, b) {
return a + b;
},
subtract(a, b) { // Shorthand
return a - b;
}
};
calculator.add(5, 3); // 8
calculator.subtract(10, 4); // 6Extract values into variables:
let person = { name: "Jerome", age: 30, city: "Atlanta" };
// Old way
let name = person.name;
let age = person.age;
// Destructuring
let { name, age } = person;
// With different variable names
let { name: personName, age: personAge } = person;
// Array destructuring
let [first, second] = ["a", "b", "c"];
// first = "a", second = "b"// Copy an object
let copy = { ...person };
// Merge objects
let merged = { ...person, email: "jerome@example.com" };
// Copy an array
let numbersCopy = [...numbers];
// Merge arrays
let combined = [...arr1, ...arr2];The DOM (Document Object Model) is how JavaScript interacts with HTML.
// By ID
let header = document.getElementById("header");
// By class (returns collection)
let cards = document.getElementsByClassName("card");
// By tag (returns collection)
let paragraphs = document.getElementsByTagName("p");
// Modern way — CSS selectors (use these)
let header = document.querySelector("#header"); // First match
let cards = document.querySelectorAll(".card"); // All matches
let firstCard = document.querySelector(".card"); // First .card
let navLinks = document.querySelectorAll("nav a"); // All links in navlet element = document.querySelector("#title");
// Text content
element.textContent = "New Title";
// HTML content
element.innerHTML = "<strong>Bold Title</strong>";
// Form values
let input = document.querySelector("#email");
input.value = "test@example.com";
let currentValue = input.value;
document.getElementById("message").innerHTML = "Hello, World!";let link = document.querySelector("a");
// Get attribute
link.getAttribute("href");
// Set attribute
link.setAttribute("href", "https://example.com");
// Remove attribute
link.removeAttribute("target");
// Check if has attribute
link.hasAttribute("target");
// Direct property access (for common attributes)
link.href = "https://example.com";
link.id = "main-link";let element = document.querySelector(".card");
// Add class
element.classList.add("active");
// Remove class
element.classList.remove("active");
// Toggle class (add if missing, remove if present)
element.classList.toggle("active");
// Check if has class
element.classList.contains("active"); // true or false
// Replace class
element.classList.replace("old-class", "new-class");let element = document.querySelector(".box");
// Direct style (camelCase)
element.style.backgroundColor = "blue";
element.style.fontSize = "20px";
element.style.display = "none";
// Get computed style
let styles = getComputedStyle(element);
styles.backgroundColor; // "rgb(0, 0, 255)"Events respond to user actions.
let button = document.querySelector("#submit-btn");
button.addEventListener("click", function() {
console.log("Button clicked!");
});
// Arrow function version
button.addEventListener("click", () => {
console.log("Button clicked!");
});
// Named function (better for removal)
function handleClick() {
console.log("Button clicked!");
}
button.addEventListener("click", handleClick);| Event | Triggered when |
|---|---|
click |
Element is clicked |
dblclick |
Element is double-clicked |
mouseenter |
Mouse enters element |
mouseleave |
Mouse leaves element |
keydown |
Key is pressed |
keyup |
Key is released |
submit |
Form is submitted |
change |
Input value changes (after blur) |
input |
Input value changes (immediately) |
focus |
Element gains focus |
blur |
Element loses focus |
scroll |
Page is scrolled |
load |
Page/image finishes loading |
button.addEventListener("click", function(event) {
console.log(event.type); // "click"
console.log(event.target); // The clicked element
console.log(event.currentTarget); // The element with the listener
});
// Form submission
form.addEventListener("submit", function(event) {
event.preventDefault(); // Stop form from submitting
// Handle form data with JavaScript instead
});
// Keyboard events
document.addEventListener("keydown", function(event) {
console.log(event.key); // "Enter", "a", "Escape"
console.log(event.code); // "Enter", "KeyA", "Escape"
});Instead of adding listeners to many elements, add one to a parent:
// Instead of this (bad for many items):
document.querySelectorAll(".card").forEach(card => {
card.addEventListener("click", handleCardClick);
});
// Do this (one listener on parent):
document.querySelector(".card-container").addEventListener("click", function(event) {
if (event.target.classList.contains("card")) {
handleCardClick(event);
}
});// Create element
let div = document.createElement("div");
// Add content and attributes
div.textContent = "Hello!";
div.classList.add("card");
div.id = "new-card";
// Add to the page
document.body.appendChild(div);
// Or insert at specific location
let container = document.querySelector(".container");
container.appendChild(div);
// Insert before another element
container.insertBefore(div, container.firstChild);function createCard(title, description) {
let card = document.createElement("div");
card.classList.add("card");
card.innerHTML = `
<h3>${title}</h3>
<p>${description}</p>
<button class="delete-btn">Delete</button>
`;
return card;
}
let newCard = createCard("My Card", "This is a description");
document.querySelector(".container").appendChild(newCard);let element = document.querySelector(".old-card");
// Modern way
element.remove();
// Old way (still works)
element.parentNode.removeChild(element);Store data in the browser that persists after page refresh.
// Save data
localStorage.setItem("username", "Jerome");
// Get data
let username = localStorage.getItem("username"); // "Jerome"
// Remove data
localStorage.removeItem("username");
// Clear all data
localStorage.clear();localStorage only stores strings. Convert with JSON:
// Save object
let user = { name: "Jerome", age: 30 };
localStorage.setItem("user", JSON.stringify(user));
// Get object
let stored = localStorage.getItem("user");
let user = JSON.parse(stored);
// Save array
let tasks = ["Learn JS", "Build portfolio", "Apply for jobs"];
localStorage.setItem("tasks", JSON.stringify(tasks));
// Get array
let tasks = JSON.parse(localStorage.getItem("tasks"));// Save function
function saveToStorage(key, data) {
localStorage.setItem(key, JSON.stringify(data));
}
// Load function with default
function loadFromStorage(key, defaultValue = null) {
let data = localStorage.getItem(key);
return data ? JSON.parse(data) : defaultValue;
}
// Usage
saveToStorage("settings", { theme: "dark", fontSize: 16 });
let settings = loadFromStorage("settings", { theme: "light", fontSize: 14 });Here's how these concepts work together:
// Data
let projects = [
{ id: 1, name: "Portfolio", category: "web", completed: true },
{ id: 2, name: "Calculator", category: "app", completed: false },
{ id: 3, name: "Blog", category: "web", completed: true }
];
// Render function
function renderProjects(projectList) {
let container = document.querySelector("#projects");
container.innerHTML = "";
projectList.forEach(project => {
let card = document.createElement("div");
card.classList.add("project-card");
if (project.completed) card.classList.add("completed");
card.innerHTML = `
<h3>${project.name}</h3>
<span class="category">${project.category}</span>
<button data-id="${project.id}">Toggle Complete</button>
`;
container.appendChild(card);
});
}
// Filter function
function filterByCategory(category) {
if (category === "all") {
renderProjects(projects);
} else {
let filtered = projects.filter(p => p.category === category);
renderProjects(filtered);
}
}
// Event listeners
document.querySelector("#filter").addEventListener("change", function(event) {
filterByCategory(event.target.value);
});
document.querySelector("#projects").addEventListener("click", function(event) {
if (event.target.tagName === "BUTTON") {
let id = parseInt(event.target.dataset.id);
let project = projects.find(p => p.id === id);
project.completed = !project.completed;
renderProjects(projects);
}
});
// Initial render
renderProjects(projects);Complete at least 30 challenges. Write each from scratch.
-
Reverse a string —
reverse("hello")→"olleh" -
Check if palindrome —
isPalindrome("racecar")→true -
Count vowels —
countVowels("hello")→2 -
Capitalize words —
capitalize("hello world")→"Hello World" -
Remove duplicates —
removeDuplicates("hello")→"helo"
-
Find largest —
findMax([1, 5, 3])→5 -
Sum all —
sum([1, 2, 3])→6 -
Remove duplicates —
unique([1, 2, 2, 3])→[1, 2, 3] -
Flatten array —
flatten([[1, 2], [3, 4]])→[1, 2, 3, 4] -
Sort by property — Sort array of objects by a given key
-
FizzBuzz — Print 1-100, "Fizz" for 3s, "Buzz" for 5s, "FizzBuzz" for both
-
Is prime —
isPrime(7)→true -
Factorial —
factorial(5)→120 -
Fibonacci —
fibonacci(7)→[0, 1, 1, 2, 3, 5, 8] -
GCD —
gcd(12, 8)→4
-
Merge objects — Combine two objects
-
Deep clone — Copy object without reference
-
Check equality — Compare two objects deeply
-
Array to object —
toObject([["a", 1], ["b", 2]])→{a: 1, b: 2} -
Group by property — Group array items by a key
Complete 10 challenges on Codewars at 8 kyu or 7 kyu level.
Focus on:
- String manipulation
- Array operations
- Basic algorithms
- Object handling
You should be able to do all of the following without looking anything up:
- Declare variables with let and const
- Use all data types appropriately
- Write conditional logic (if/else, switch, ternary)
- Write loops (for, while, for...of)
- Create and call functions
- Work with arrays and all common methods
- Work with objects
- Select and modify DOM elements
- Handle events
- Create and remove elements dynamically
- Use localStorage
Keep a JavaScript file with all 30+ challenge solutions.
You'll reference these when building your portfolio features and during your interview.
Enjoy exploring the endless possibilities of web interactivity. 🚀
Next up: Module 6: Capstone — Your Portfolio