JavaScript Tutorial
JavaScript is the programming language of the web. It makes pages interactive - from form validation to real-time updates, animations, and full web applications (SPAs).
What is JavaScript?
- Created by Brendan Eich in 1995 (originally called Mocha, then LiveScript).
- Runs in the browser (client-side) AND on servers (Node.js).
- Dynamically typed - no need to declare variable types.
- Modern JavaScript uses the ECMAScript standard (ES6+ = ES2015+).
HTML
<!-- Inline JS -->
<script>
alert("Hello, World!");
</script>
<!-- External JS (recommended) -->
<script src="app.js" defer></script>
JavaScript Output
JavaScript
// Write to browser console (debug)
console.log("Hello");
console.warn("Warning!");
console.error("Error!");
console.table([{name:"Alice", age:25}]);
// Alert / Confirm / Prompt dialogs
alert("Hello World!");
const ok = confirm("Are you sure?"); // returns true/false
const name = prompt("Enter your name:", ""); // returns string
// Write into HTML
document.getElementById("demo").innerHTML = "<b>Hi!</b>";
document.getElementById("demo").textContent = "Safe text (no HTML)";
// Write to HTML document (only during loading)
document.write("Hello"); // overwrites if called after load
Variables
JavaScript
// var - function-scoped, hoisted, re-declarable (avoid in modern JS)
var name = "Alice";
// let - block-scoped, not re-declarable, can be reassigned
let age = 25;
age = 26;
// const - block-scoped, cannot be reassigned (use for most variables)
const PI = 3.14159;
const user = { name: "Alice" };
user.name = "Bob"; // OK - object contents can change
// Rules
let myVar_1 = "valid";
// let 1var = "invalid"; // starts with number - error
// Reserved words (let, class, for) can't be variable names
// Destructuring assignment
const [a, b] = [1, 2];
const { x, y } = { x: 10, y: 20 };
Data Types
| Type | Example | typeof |
|---|---|---|
| String | "Hello", 'World', `Template` | "string" |
| Number | 42, 3.14, -7, Infinity, NaN | "number" |
| BigInt | 9007199254740991n | "bigint" |
| Boolean | true, false | "boolean" |
| Undefined | (variable declared but not assigned) | "undefined" |
| Null | null (intentional absence) | "object" ?? |
| Symbol | Symbol("id") | "symbol" |
| Object | {}, [], null, new Date() | "object" |
| Function | function(){}, ()=>{} | "function" |
JavaScript
// Type checking
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" (historical bug!)
typeof [] // "object"
Array.isArray([]) // true (correct check)
null === null // true
// Type conversion
Number("42") // 42
Number("") // 0
Number("abc") // NaN
String(42) // "42"
Boolean(0) // false (falsy)
Boolean("") // false (falsy)
Boolean("hello") // true
Operators
JavaScript
// Arithmetic
5 + 3 // 8 addition
5 - 3 // 2 subtraction
5 * 3 // 15 multiplication
10 / 3 // 3.33 division
10 % 3 // 1 modulus (remainder)
2 ** 8 // 256 exponentiation
// Assignment
let x = 10;
x += 5; // x = 15
x -= 3; // x = 12
x *= 2; // x = 24
x /= 4; // x = 6
x **= 2; // x = 36
x++; // post-increment ? x = 37
++x; // pre-increment
// Comparison (always use ===)
5 == "5" // true (loose - type coercion)
5 === "5" // false (strict - no coercion) ?
5 !== "5" // true (strict not-equal)
// Logical
true && false // false (AND)
true || false // true (OR)
!true // false (NOT)
// Nullish coalescing ??
const name = null ?? "Guest"; // "Guest"
const age = 0 ?? 18; // 0 (0 is NOT null/undefined)
// Optional chaining ?.
const city = user?.address?.city; // undefined if user or address is null
// Ternary
const label = age >= 18 ? "Adult" : "Minor";
Strings
JavaScript
const s = "Hello, World!";
s.length // 13
s.toUpperCase() // "HELLO, WORLD!"
s.toLowerCase() // "hello, world!"
s.indexOf("o") // 4 (first occurrence)
s.lastIndexOf("o")// 8
s.includes("World") // true
s.startsWith("He") // true
s.endsWith("!") // true
s.slice(7, 12) // "World"
s.substring(7, 12)// "World"
s.replace("World", "JS") // "Hello, JS!"
s.replaceAll("l", "L") // "HeLLo, WorLd!"
s.split(", ") // ["Hello", "World!"]
s.trim() // remove leading/trailing spaces
s.padStart(20, "*") // "***Hello, World!"
s.padEnd(20, "*") // "Hello, World!***"
s.repeat(2) // "Hello, World!Hello, World!"
s.charAt(0) // "H"
s.charCodeAt(0) // 72
// Template literals (backtick)
const name = "Alice";
const greet = `Hello, ${name}! You are ${25 + 1} years old.`;
const multiline = `
Line 1
Line 2
`;
// String.raw (no escape processing)
String.raw`C:\new\folder` // "C:\\new\\folder"
Numbers
JavaScript
const n = 3.14159;
n.toFixed(2) // "3.14"
n.toPrecision(4) // "3.142"
n.toString() // "3.14159"
n.toString(16) // hex conversion
Number.isInteger(42) // true
Number.isNaN(NaN) // true
Number.isFinite(Infinity) // false
Number.parseInt("42px") // 42
Number.parseFloat("3.14") // 3.14
Number.MAX_SAFE_INTEGER // 2^53 - 1
// Math object
Math.round(4.6) // 5
Math.floor(4.9) // 4
Math.ceil(4.1) // 5
Math.abs(-5) // 5
Math.max(1, 5, 3) // 5
Math.min(1, 5, 3) // 1
Math.sqrt(16) // 4
Math.pow(2, 10) // 1024
Math.random() // 0-0.9999...
Math.trunc(4.9) // 4 (integer part)
Math.sign(-5) // -1
// Random integer between min and max (inclusive)
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Arrays
JavaScript
const fruits = ["apple", "banana", "cherry"];
// Basic operations
fruits.length // 3
fruits[0] // "apple"
fruits.push("date") // add to end ? 4
fruits.pop() // remove from end ? "date"
fruits.unshift("avocado") // add to start
fruits.shift() // remove from start
// Finding
fruits.indexOf("banana") // 1
fruits.includes("cherry") // true
fruits.find(f => f.startsWith("b")) // "banana"
fruits.findIndex(f => f.length > 5) // 1
// Transforming (non-mutating - return new array)
fruits.map(f => f.toUpperCase()) // ["APPLE", "BANANA", ...]
fruits.filter(f => f.length > 5) // ["banana", "cherry"]
fruits.reduce((acc, f) => acc + f, "")// "applebananacherry"
fruits.sort() // alphabetical sort
fruits.sort((a, b) => a.localeCompare(b))
fruits.reverse()
fruits.slice(1, 3) // ["banana", "cherry"] (no mutation)
fruits.splice(1, 1) // removes 1 element at index 1
fruits.concat(["elderberry"])
fruits.flat() // flatten nested arrays
fruits.flatMap(f => [f, f.length])
fruits.every(f => f.length > 3) // true if all match
fruits.some(f => f.startsWith("a")) // true if any match
fruits.join(", ") // "apple, banana, cherry"
// Spread
const copy = [...fruits];
const merged = [...fruits, "elderberry", "fig"];
// Destructuring
const [first, second, ...rest] = fruits;
// Array.from
Array.from("hello") // ["h","e","l","l","o"]
Array.from({length: 3}, (_,i) => i+1) // [1, 2, 3]
Array.of(1, 2, 3) // [1, 2, 3]
Objects
JavaScript
const user = {
name: "Alice",
age: 25,
email: "alice@example.com",
greet() { return `Hi, I'm ${this.name}`; },
address: { city: "Mumbai", country: "India" }
};
// Access
user.name // "Alice"
user["age"] // 25
user.address.city // "Mumbai"
user.greet() // "Hi, I'm Alice"
// Modify
user.age = 26;
user.phone = "+91-999";
delete user.email;
// Check property existence
"name" in user // true
user.hasOwnProperty("name") // true
// Iterate
Object.keys(user) // ["name", "age", ...]
Object.values(user) // ["Alice", 26, ...]
Object.entries(user) // [["name","Alice"], ...]
for (const [key, val] of Object.entries(user)) {
console.log(`${key}: ${val}`);
}
// Spread / merge
const copy = { ...user };
const merged = { ...user, role: "admin" };
// Destructuring
const { name, age, address: { city } } = user;
const { name: n = "Guest" } = {}; // default value
// Object.assign
const target = Object.assign({}, user, { role: "admin" });
// Object.freeze (immutable)
const config = Object.freeze({ debug: false });
// config.debug = true; // silently fails
// Computed property names
const key = "color";
const style = { [key]: "red" }; // { color: "red" }
Conditionals
JavaScript
// if / else if / else
const score = 75;
if (score >= 90) console.log("A");
else if (score >= 80) console.log("B");
else if (score >= 70) console.log("C");
else console.log("F");
// switch
const day = "Monday";
switch (day) {
case "Saturday":
case "Sunday":
console.log("Weekend"); break;
case "Monday":
console.log("Back to work"); break;
default:
console.log("Weekday");
}
// Ternary operator
const status = score >= 50 ? "Pass" : "Fail";
// Short-circuit evaluation
const name = userInput || "Guest"; // fallback if falsy
const city = user && user.address && user.address.city;
// Nullish coalescing (only for null/undefined)
const theme = savedTheme ?? "light";
Loops
JavaScript
// for loop
for (let i = 0; i < 5; i++) { console.log(i); }
// while loop
let i = 0;
while (i < 5) { console.log(i); i++; }
// do...while (runs at least once)
do { console.log(i); i++; } while (i < 5);
// for...of (iterate values - arrays, strings, Sets, Maps)
const nums = [10, 20, 30];
for (const n of nums) { console.log(n); }
// for...in (iterate keys of object)
const obj = { a: 1, b: 2 };
for (const key in obj) { console.log(key, obj[key]); }
// forEach (array method)
nums.forEach((n, index) => console.log(index, n));
// break and continue
for (let i = 0; i < 10; i++) {
if (i === 5) break; // exit loop
if (i % 2 === 0) continue; // skip even numbers
console.log(i);
}
// Labelled break (nested loops)
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) break outer;
console.log(i, j);
}
}
Functions
JavaScript
// Function declaration (hoisted)
function add(a, b) { return a + b; }
// Function expression (not hoisted)
const multiply = function(a, b) { return a * b; };
// Default parameters
function greet(name = "World") { return `Hello, ${name}!`; }
// Rest parameters
function sum(...nums) { return nums.reduce((a, b) => a + b, 0); }
sum(1, 2, 3, 4); // 10
// Higher-order functions
function repeat(fn, n) { for (let i = 0; i < n; i++) fn(i); }
repeat(console.log, 3); // 0, 1, 2
// IIFE (Immediately Invoked Function Expression)
(function() { console.log("Runs immediately"); })();
(() => { console.log("Arrow IIFE"); })();
// Callback function
function fetchData(callback) {
setTimeout(() => callback("data ready"), 1000);
}
Arrow Functions
JavaScript
// Arrow function syntax
const add = (a, b) => a + b;
const square = n => n * n; // single parameter, no parens needed
const greet = () => "Hello!"; // no parameters
// Multi-line body
const multiply = (a, b) => {
const result = a * b;
return result;
};
// Return object literal (wrap in parens)
const makeUser = name => ({ name, role: "user" });
// Arrow functions have NO own 'this'
// They inherit 'this' from enclosing scope
class Timer {
start() {
setInterval(() => {
this.tick(); // 'this' refers to Timer instance ?
}, 1000);
}
tick() { console.log("tick"); }
}
DOM Manipulation
JavaScript
// Selecting elements
const el = document.getElementById("myId");
const els = document.getElementsByClassName("myClass");
const paras = document.getElementsByTagName("p");
const btn = document.querySelector(".btn"); // first match
const btns = document.querySelectorAll(".btn"); // all matches
// Modifying content
el.innerHTML = "<b>Bold text</b>"; // sets HTML (XSS risk with user input!)
el.textContent = "Safe text"; // safe - no HTML parsing
el.innerText = "Visible text only";
// Attributes
el.getAttribute("href");
el.setAttribute("href", "https://example.com");
el.removeAttribute("disabled");
el.hasAttribute("required"); // true/false
el.dataset.userId; // reads data-user-id attribute
// CSS Classes
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("open");
el.classList.contains("active"); // true/false
// Style
el.style.color = "red";
el.style.fontSize = "18px";
el.style.display = "none";
// Create & insert elements
const div = document.createElement("div");
div.textContent = "New element";
div.className = "card";
document.body.appendChild(div); // add to end of body
document.body.insertBefore(div, nextEl); // insert before element
el.prepend(div); // add first child
el.after(div); // insert after element
el.before(div); // insert before element
el.remove(); // remove from DOM
el.replaceWith(newEl); // replace element
// Traversal
el.parentElement;
el.children; // HTMLCollection of child elements
el.firstElementChild;
el.lastElementChild;
el.nextElementSibling;
el.previousElementSibling;
Events
JavaScript
// addEventListener (preferred method)
btn.addEventListener("click", function(event) {
console.log("Clicked!", event.target);
});
// Remove listener
function handler(e) { console.log(e); }
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);
// Event object
el.addEventListener("click", (e) => {
e.preventDefault(); // stop default action (e.g. form submit, link)
e.stopPropagation(); // stop event bubbling up DOM
console.log(e.type); // "click"
console.log(e.target); // element that was clicked
console.log(e.clientX, e.clientY); // mouse coords
console.log(e.key); // keyboard key
});
// Common events
"click" "dblclick" "mouseenter" "mouseleave"
"mouseover" "mouseout" "mousemove" "mousedown" "mouseup"
"keydown" "keyup" "keypress"
"submit" "change" "input" "focus" "blur"
"scroll" "resize" "load" "DOMContentLoaded"
"touchstart" "touchend" "touchmove"
// Event delegation (efficient - add listener to parent)
document.addEventListener("click", (e) => {
if (e.target.matches(".btn")) handleBtnClick(e.target);
});
// Form submit
form.addEventListener("submit", (e) => {
e.preventDefault();
const data = new FormData(form);
console.log(data.get("email"));
});
Promises & Async/Await
JavaScript
// Promise
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("Done!"), 1000);
// setTimeout(() => reject(new Error("Fail")), 1000);
});
p.then(result => console.log(result))
.catch(err => console.error(err))
.finally(() => console.log("Always runs"));
// Promise.all (wait for multiple)
Promise.all([fetch(url1), fetch(url2)])
.then(([r1, r2]) => console.log(r1, r2));
// Promise.race (first to finish)
Promise.race([p1, p2]).then(result => console.log(result));
// Promise.allSettled (all results, even rejected)
Promise.allSettled([p1, p2]).then(results => results.forEach(r => console.log(r.status)));
// async/await (syntactic sugar over Promises)
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
return data;
} catch (err) {
console.error("Failed:", err.message);
}
}
// Parallel async
async function loadAll() {
const [users, posts] = await Promise.all([
fetchUsers(), fetchPosts()
]);
return { users, posts };
}
Fetch API
JavaScript
// GET request
async function getUsers() {
const res = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await res.json();
console.log(data);
}
// POST request
async function createPost(post) {
const res = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(post)
});
return await res.json();
}
// PUT / PATCH / DELETE
await fetch(`/api/items/${id}`, { method: "DELETE" });
await fetch(`/api/items/${id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ field: "newValue" })
});
// With authentication header
await fetch("/api/protected", {
headers: { "Authorization": `Bearer ${token}` }
});
Classes & OOP
JavaScript
class Animal {
// Private field
#name;
constructor(name, sound) {
this.#name = name;
this.sound = sound;
}
speak() { return `${this.#name} says ${this.sound}!`; }
get name() { return this.#name; }
set name(value) { this.#name = value; }
static create(name, sound) { return new Animal(name, sound); }
}
// Inheritance
class Dog extends Animal {
#breed;
constructor(name, breed) {
super(name, "Woof"); // call parent constructor
this.#breed = breed;
}
fetch() { return `${this.name} fetches the ball!`; }
speak() { // override parent method
return super.speak() + " *tail wagging*";
}
}
const dog = new Dog("Rex", "Labrador");
dog.speak(); // "Rex says Woof! *tail wagging*"
dog.fetch(); // "Rex fetches the ball!"
dog instanceof Dog; // true
dog instanceof Animal; // true
ES6+ Features
JavaScript - Modern Syntax
// ---- Destructuring ----
const [a, , b] = [1, 2, 3]; // a=1, b=3
const { x = 0, y = 0 } = point; // with defaults
const { name: alias } = { name: "Alice" }; // rename
// ---- Spread & Rest ----
const arr = [...arr1, ...arr2];
const obj = { ...obj1, ...obj2 };
function fn(...args) { return args; }
// ---- Template Literals ----
const message = `Hello ${name}, you scored ${score * 2}!`;
// ---- Enhanced Object Literals ----
const name = "Alice", age = 25;
const user = { name, age, greet() { return `Hi ${this.name}`; } };
// ---- Symbol ----
const id = Symbol("id");
user[id] = 123; // non-enumerable, private
// ---- Map & Set ----
const map = new Map([["a", 1], ["b", 2]]);
map.set("c", 3); map.get("a"); // 1
map.has("b"); // true
map.size; // 3
for (const [key, val] of map) { ... }
const set = new Set([1, 2, 2, 3]); // {1, 2, 3}
set.add(4); set.has(2); // true
[...set]; // [1, 2, 3, 4]
// ---- WeakMap & WeakRef ----
const weakMap = new WeakMap(); // keys must be objects, no iteration
// ---- Generators ----
function* counter() {
let i = 0;
while (true) yield i++;
}
const gen = counter();
gen.next().value; // 0
gen.next().value; // 1
// ---- Proxy ----
const proxy = new Proxy(target, {
get(obj, key) { return key in obj ? obj[key] : "default"; },
set(obj, key, val) { obj[key] = val; return true; }
});
// ---- String methods (ES2021+) ----
" hello ".trimStart().trimEnd();
"ha".repeat(3); // "hahaha"
"abc".at(-1); // "c"
"abc".replaceAll("a", "A");
// ---- Array methods (ES2022+) ----
[1,[2,[3]]].flat(Infinity); // [1,2,3]
[1,2,3].at(-1); // 3
arr.findLast(x => x > 2); // last match
Array Methods in Practice
Modern JavaScript relies heavily on array methods because they let you transform data without manual index loops.
JavaScript
const products = [
{ name: 'Keyboard', price: 2500, stock: 12 },
{ name: 'Mouse', price: 1200, stock: 0 },
{ name: 'Monitor', price: 18000, stock: 4 }
];
const inStock = products.filter(p => p.stock > 0);
const names = products.map(p => p.name);
const totalValue = products.reduce((sum, p) => sum + p.price * p.stock, 0);
const expensive = products.find(p => p.price > 10000);
const allAvailable = products.every(p => p.stock > 0);
const hasSoldOut = products.some(p => p.stock === 0);
JSON
JSON is the most common format for sending data between browsers, servers, and APIs. Students should understand the difference between a JavaScript object and a JSON string.
JavaScript
const user = { id: 1, name: 'Aisha', admin: false };
const jsonText = JSON.stringify(user);
console.log(jsonText); // '{"id":1,"name":"Aisha","admin":false}'
const parsedUser = JSON.parse(jsonText);
console.log(parsedUser.name); // 'Aisha'
localStorage.setItem('currentUser', JSON.stringify(user));
const savedUser = JSON.parse(localStorage.getItem('currentUser') || 'null');
Event Loop
JavaScript runs on a single main thread, but browsers and runtimes provide timers, network APIs, and task queues. The event loop decides when queued work can run.
JavaScript
console.log('A');
setTimeout(() => console.log('B - timer'), 0);
Promise.resolve().then(() => console.log('C - microtask'));
console.log('D');
// Output:
// A
// D
// C - microtask
// B - timer
Important Promise callbacks run before timer callbacks because microtasks are processed before the next macrotask.