JavaScript brings web pages to life. It's the programming language of the browser, enabling interactivity, dynamic content, and modern web applications. It's also used on servers with Node.js.
Why JavaScript?
- Universal: Runs in every browser, no installation needed
- Versatile: Frontend, backend, mobile apps, desktop apps
- In demand: Most popular programming language (Stack Overflow surveys)
- Immediate feedback: See results instantly in the browser
Running JavaScript
<!-- In HTML file -->
<script>
console.log("Hello, World!");
</script>
<!-- Or link external file -->
<script src="script.js"></script>
<!-- In browser console (F12 or Cmd+Option+J) -->
console.log("Hello from console!"); Variables & Data Types
Declaring Variables
// let - can be reassigned
let age = 25;
age = 26; // OK
// const - cannot be reassigned (preferred for most cases)
const name = "Alice";
// name = "Bob"; // Error!
// var - old way, avoid using (function-scoped, hoisted)
var oldWay = "legacy"; Data Types
// Primitive types
const string = "Hello"; // Text
const number = 42; // Numbers (integers and decimals)
const decimal = 3.14;
const boolean = true; // true or false
const nothing = null; // Intentional empty value
const notDefined = undefined; // Not yet assigned
const unique = Symbol("id"); // Unique identifier
const bigInt = 9007199254740991n; // Very large integers
// Reference types
const array = [1, 2, 3]; // List of values
const object = { name: "Alice" }; // Key-value pairs
const func = function() {}; // Functions are objects too
// Check type
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" (historical bug)
typeof [] // "object"
typeof {} // "object" Strings
// String creation
const single = 'Hello';
const double = "World";
const template = `Hello, ${name}!`; // Template literal
// String methods
const text = "JavaScript";
text.length; // 10
text.toUpperCase(); // "JAVASCRIPT"
text.toLowerCase(); // "javascript"
text.includes("Script"); // true
text.indexOf("S"); // 4
text.slice(0, 4); // "Java"
text.split(""); // ["J","a","v","a","S","c","r","i","p","t"]
text.replace("Java", "Type"); // "TypeScript"
// Template literals (backticks)
const name = "Alice";
const greeting = `Hello, ${name}!
This is a multi-line string.`; Operators & Control Flow
Operators
// Arithmetic
5 + 3 // 8
10 - 4 // 6
3 * 4 // 12
15 / 3 // 5
17 % 5 // 2 (remainder)
2 ** 3 // 8 (exponentiation)
// Comparison
5 == "5" // true (loose equality, converts types)
5 === "5" // false (strict equality, recommended)
5 !== "5" // true
5 > 3 // true
5 >= 5 // true
// Logical
true && false // false (AND)
true || false // true (OR)
!true // false (NOT)
// Assignment
let x = 10;
x += 5; // x = x + 5 = 15
x -= 3; // x = 12
x *= 2; // x = 24
x++; // x = 25
x--; // x = 24 Conditionals
// if-else
const age = 18;
if (age >= 21) {
console.log("Can drink alcohol");
} else if (age >= 18) {
console.log("Can vote");
} else {
console.log("Minor");
}
// Ternary operator
const status = age >= 18 ? "adult" : "minor";
// Switch
const day = "Monday";
switch (day) {
case "Monday":
case "Tuesday":
console.log("Weekday");
break;
case "Saturday":
case "Sunday":
console.log("Weekend");
break;
default:
console.log("Invalid day");
} Loops
// for loop
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// while loop
let count = 0;
while (count < 3) {
console.log(count);
count++;
}
// do-while (runs at least once)
let num = 0;
do {
console.log(num);
num++;
} while (num < 3);
// for...of (iterate values)
const fruits = ["apple", "banana", "cherry"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in (iterate keys/indices)
const person = { name: "Alice", age: 30 };
for (const key in person) {
console.log(key, person[key]);
} Functions
Function Declaration
// Function declaration (hoisted)
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("Alice")); // "Hello, Alice!"
// Function expression
const greet = function(name) {
return `Hello, ${name}!`;
};
// Arrow function (modern, concise)
const greet = (name) => {
return `Hello, ${name}!`;
};
// Arrow function (short form for single expression)
const greet = name => `Hello, ${name}!`;
const add = (a, b) => a + b; Parameters and Arguments
// Default parameters
function greet(name = "World") {
return `Hello, ${name}!`;
}
greet(); // "Hello, World!"
greet("Alice"); // "Hello, Alice!"
// Rest parameters (gather remaining arguments)
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3, 4); // 10
// Destructuring parameters
function createUser({ name, age, city = "Unknown" }) {
return `${name}, ${age}, from ${city}`;
}
createUser({ name: "Alice", age: 30 }); Higher-Order Functions
// Functions can take functions as arguments
function doTwice(fn) {
fn();
fn();
}
doTwice(() => console.log("Hello!"));
// Functions can return functions
function multiplier(factor) {
return (number) => number * factor;
}
const double = multiplier(2);
const triple = multiplier(3);
double(5); // 10
triple(5); // 15 Arrays
// Creating arrays
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "two", true, null];
const empty = [];
// Accessing elements (0-indexed)
numbers[0]; // 1
numbers[2]; // 3
numbers.length; // 5
// Modifying arrays
numbers.push(6); // Add to end: [1,2,3,4,5,6]
numbers.pop(); // Remove from end: [1,2,3,4,5]
numbers.unshift(0); // Add to start: [0,1,2,3,4,5]
numbers.shift(); // Remove from start: [1,2,3,4,5]
numbers.splice(2, 1); // Remove 1 item at index 2 Essential Array Methods
const numbers = [1, 2, 3, 4, 5];
// forEach - iterate (no return value)
numbers.forEach(n => console.log(n));
// map - transform each element
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]
// filter - keep elements that pass test
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4]
// find - get first matching element
const found = numbers.find(n => n > 3);
// 4
// reduce - accumulate to single value
const sum = numbers.reduce((total, n) => total + n, 0);
// 15
// some/every - test conditions
numbers.some(n => n > 4); // true (at least one)
numbers.every(n => n > 0); // true (all of them)
// includes - check if exists
numbers.includes(3); // true
// sort - sort in place
const names = ["Charlie", "Alice", "Bob"];
names.sort(); // ["Alice", "Bob", "Charlie"]
// Chaining methods
const result = numbers
.filter(n => n % 2 === 0)
.map(n => n * 10);
// [20, 40] Spread and Destructuring
// Spread operator (...)
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
const copy = [...arr1]; // Create shallow copy
// Destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first = 1, second = 2, rest = [3, 4, 5]
const [a, , c] = [1, 2, 3]; // Skip elements
// a = 1, c = 3 Objects
// Creating objects
const person = {
name: "Alice",
age: 30,
city: "New York",
hobbies: ["reading", "coding"],
greet() {
return `Hi, I'm ${this.name}`;
}
};
// Accessing properties
person.name; // "Alice"
person["age"]; // 30
person.greet(); // "Hi, I'm Alice"
// Modifying properties
person.age = 31;
person.email = "alice@example.com"; // Add new property
delete person.city; // Remove property
// Check if property exists
"name" in person; // true
person.hasOwnProperty("name"); // true Object Methods
const user = { name: "Alice", age: 30, city: "NYC" };
// Get keys, values, entries
Object.keys(user); // ["name", "age", "city"]
Object.values(user); // ["Alice", 30, "NYC"]
Object.entries(user); // [["name","Alice"], ["age",30], ["city","NYC"]]
// Spread and merge
const defaults = { theme: "light", lang: "en" };
const settings = { theme: "dark" };
const merged = { ...defaults, ...settings };
// { theme: "dark", lang: "en" }
// Destructuring
const { name, age } = user;
// name = "Alice", age = 30
const { name: userName, city = "Unknown" } = user;
// userName = "Alice", city = "NYC" DOM Manipulation
The Document Object Model (DOM) represents your HTML as a tree of objects. JavaScript can read and modify this tree to change what users see.
Selecting Elements
// By ID (returns one element)
const header = document.getElementById("header");
// By class (returns collection)
const items = document.getElementsByClassName("item");
// By tag (returns collection)
const paragraphs = document.getElementsByTagName("p");
// Modern selectors (recommended)
const first = document.querySelector(".item"); // First match
const all = document.querySelectorAll(".item"); // All matches
const nested = document.querySelector("nav > ul > li"); Modifying Elements
const element = document.querySelector("#myDiv");
// Content
element.textContent = "New text"; // Text only
element.innerHTML = "<strong>Bold</strong>"; // HTML (careful with XSS)
// Attributes
element.setAttribute("class", "active");
element.getAttribute("id");
element.removeAttribute("disabled");
element.id = "newId";
// Classes
element.classList.add("active");
element.classList.remove("hidden");
element.classList.toggle("selected");
element.classList.contains("active"); // true/false
// Styles
element.style.color = "red";
element.style.backgroundColor = "blue";
element.style.display = "none"; Creating Elements
// Create new element
const newDiv = document.createElement("div");
newDiv.textContent = "Hello!";
newDiv.className = "message";
// Add to page
document.body.appendChild(newDiv);
parentElement.insertBefore(newDiv, referenceElement);
// Modern insertion methods
parent.append(newDiv); // Add to end
parent.prepend(newDiv); // Add to start
element.before(newDiv); // Before element
element.after(newDiv); // After element
element.replaceWith(newDiv); // Replace element
// Remove element
element.remove(); Events
Events let your code respond to user actions like clicks, typing, and scrolling.
Adding Event Listeners
const button = document.querySelector("#myButton");
// addEventListener (recommended)
button.addEventListener("click", function(event) {
console.log("Button clicked!");
console.log(event.target); // The clicked element
});
// Arrow function
button.addEventListener("click", (e) => {
console.log("Clicked!");
});
// Remove event listener
function handleClick() {
console.log("Clicked!");
}
button.addEventListener("click", handleClick);
button.removeEventListener("click", handleClick); Common Events
// Mouse events
element.addEventListener("click", handler);
element.addEventListener("dblclick", handler);
element.addEventListener("mouseenter", handler);
element.addEventListener("mouseleave", handler);
// Keyboard events
document.addEventListener("keydown", (e) => {
console.log(e.key); // "Enter", "Escape", "a", etc.
});
// Form events
form.addEventListener("submit", (e) => {
e.preventDefault(); // Stop form from submitting
// Handle form data
});
input.addEventListener("input", (e) => {
console.log(e.target.value); // As user types
});
input.addEventListener("change", handler); // When value changes
// Window events
window.addEventListener("load", handler); // Page loaded
window.addEventListener("scroll", handler); // User scrolls
window.addEventListener("resize", handler); // Window resized Event Delegation
// Instead of adding listeners to many elements...
// Add one listener to the parent
document.querySelector("#todoList").addEventListener("click", (e) => {
if (e.target.classList.contains("delete-btn")) {
e.target.parentElement.remove();
}
if (e.target.classList.contains("toggle-btn")) {
e.target.parentElement.classList.toggle("completed");
}
}); Asynchronous JavaScript
JavaScript is single-threaded but can handle async operations (network requests, timers) without blocking. This is crucial for responsive web applications.
Callbacks
// setTimeout - run code after delay
setTimeout(() => {
console.log("Runs after 2 seconds");
}, 2000);
// setInterval - run code repeatedly
const intervalId = setInterval(() => {
console.log("Runs every second");
}, 1000);
clearInterval(intervalId); // Stop interval Promises
// Creating a promise
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve("Data loaded!");
} else {
reject("Error loading data");
}
});
// Using a promise
promise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log("Done"));
// Promise methods
Promise.all([promise1, promise2]) // Wait for all
Promise.race([promise1, promise2]) // First to complete
Promise.any([promise1, promise2]) // First to succeed Async/Await
// async function returns a Promise
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error("User not found");
}
const user = await response.json();
return user;
} catch (error) {
console.error("Error:", error.message);
throw error;
}
}
// Using async function
async function displayUser() {
const user = await fetchUser(123);
console.log(user.name);
}
displayUser(); Fetch API
// GET request
async function getUsers() {
const response = await fetch("/api/users");
const users = await response.json();
return users;
}
// POST request
async function createUser(userData) {
const response = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
});
return response.json();
}
// With error handling
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Fetch failed:", error);
throw error;
}
} Next Steps
- React - Build modern user interfaces
- Node.js - Run JavaScript on the server
- API Design - Build and consume web APIs
- Practice Projects - Apply your skills