What is JavaScript?
JavaScript is a high-level, dynamic, interpreted language that powers the modern web. Originally designed for browsers, it now runs everywhere: servers, mobile apps, desktop, IoT, and more.
Universal
Runs in every browser, on servers (Node.js), mobile (React Native), desktop (Electron), and more.
Dynamic & Flexible
Weakly typed, prototype-based, first-class functions. Adapts to many programming styles.
Event-Driven
Built for asynchronous operations. Perfect for handling user interactions and I/O.
Massive Ecosystem
npm has millions of packages. Frameworks like React, Vue, Angular, Express, Next.js, and more.
Basics
Variables
// const: cannot reassign (preferred) const x = 42; const name = 'Alice'; // let: can reassign, block-scoped let count = 0; count = 1; // var: old style, function-scoped (avoid) var legacy = 'use const or let instead';
Console & Comments
// Single-line comment /* Multi-line comment */ // Console output console.log('Hello, World!'); console.warn('Warning message'); console.error('Error message'); console.table([{ name: 'Alice' }, { name: 'Bob' }]);
Operators
// Arithmetic 1 + 2 // 3 5 - 2 // 3 3 * 4 // 12 10 / 2 // 5 10 % 3 // 1 (modulo) 2 ** 3 // 8 (exponentiation) // Comparison (use === and !==) 5 === 5 // true (strict equality) 5 !== '5' // true (strict inequality) 5 == '5' // true (loose, avoid!) 5 > 3 // true // Logical true && false // false (AND) true || false // true (OR) !true // false (NOT) x ?? 0 // nullish coalescing (0 if x is null/undefined)
Control Flow
// if/else if (x > 0) { console.log('positive'); } else if (x < 0) { console.log('negative'); } else { console.log('zero'); } // Ternary const result = x > 0 ? 'positive' : 'non-positive'; // for loop for (let i = 0; i < 10; i++) { console.log(i); } // while while (x < 10) { x++; } // for...of (iterate values) for (const item of array) { console.log(item); } // for...in (iterate keys - avoid for arrays) for (const key in object) { console.log(key); }
Switch Statement
switch (value) { case 'a': console.log('A'); break; case 'b': case 'c': console.log('B or C'); break; default: console.log('Other'); }
Types
Primitive Types
| Type | Example | Notes |
|---|---|---|
| Number | 42, 3.14, Infinity, NaN |
All numbers are 64-bit floats |
| BigInt | 9007199254740991n |
Arbitrary precision integers |
| String | 'hello', "world", `template` |
UTF-16 encoded text |
| Boolean | true, false |
Logical values |
| undefined | undefined |
Uninitialized or missing |
| null | null |
Intentional absence of value |
| Symbol | Symbol('desc') |
Unique identifier |
Strings
// Creation const single = 'single quotes'; const double = "double quotes"; const name = 'Alice'; // Template literals (backticks) const greeting = `Hello, ${name}!`; const multiline = `Line 1 Line 2`; // String methods 'hello'.length // 5 'hello'.toUpperCase() // 'HELLO' 'HELLO'.toLowerCase() // 'hello' 'hello world'.split(' ') // ['hello', 'world'] 'hello'.includes('ell') // true 'hello'.startsWith('he') // true 'hello'.endsWith('lo') // true 'hello'.slice(1, 4) // 'ell' 'hello'.replace('l', 'L') // 'heLlo' (first only) 'hello'.replaceAll('l', 'L') // 'heLLo' ' trim '.trim() // 'trim'
Type Checking & Conversion
// typeof operator typeof 42 // 'number' typeof 'hello' // 'string' typeof true // 'boolean' typeof undefined // 'undefined' typeof null // 'object' (quirk!) typeof {} // 'object' typeof [] // 'object' (arrays are objects) typeof function() {} // 'function' // Type conversion String(42) // '42' Number('42') // 42 Number('42px') // NaN parseInt('42px') // 42 parseFloat('3.14') // 3.14 Boolean(0) // false Boolean(1) // true // Falsy values (everything else is truthy) false, 0, 0n, '', null, undefined, NaN
Math
Math.round(4.7) // 5 Math.ceil(4.1) // 5 Math.floor(4.9) // 4 Math.abs(-5) // 5 Math.max(1, 2, 3) // 3 Math.min(1, 2, 3) // 1 Math.random() // 0-1 (exclusive) Math.sqrt(16) // 4 Math.pow(2, 3) // 8 Math.PI // 3.14159...
Functions
Function Declaration
// Basic function function greet(name) { return `Hello, ${name}!`; } // With default parameters function greet(name = 'World') { return `Hello, ${name}!`; } // Multiple parameters function add(a, b) { return a + b; }
Arrow Functions
// Concise syntax const add = (a, b) => a + b; // With block body const greet = (name) => { const message = `Hello, ${name}!`; return message; }; // Single parameter (parentheses optional) const double = x => x * 2; // No parameters const getRandom = () => Math.random(); // Returning object literal (wrap in parentheses) const makePerson = (name, age) => ({ name, age });
Rest Parameters & Spread
// Rest parameters (collect arguments) function sum(...numbers) { return numbers.reduce((a, b) => a + b, 0); } sum(1, 2, 3, 4); // 10 // Spread operator (expand array) const arr1 = [1, 2]; const arr2 = [3, 4]; const combined = [...arr1, ...arr2]; // [1, 2, 3, 4] // Spread with objects const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3 }; const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3 }
Higher-Order Functions
// Function that returns a function function makeMultiplier(factor) { return (x) => x * factor; } const double = makeMultiplier(2); double(5); // 10 // Function that takes a function function applyTwice(fn, x) { return fn(fn(x)); } applyTwice(x => x * 2, 3); // 12
Immediately Invoked Function Expression (IIFE)
(function() { console.log('Runs immediately'); })(); // Arrow IIFE (() => { console.log('Also runs immediately'); })();
Objects & Arrays
Objects
// Object literal const person = { name: 'Alice', age: 30, greet() { return `Hi, I'm ${this.name}`; } }; // Access properties person.name // 'Alice' person['age'] // 30 // Add/modify properties person.email = 'alice@example.com'; // Delete property delete person.age; // Check property exists 'name' in person // true person.hasOwnProperty('name') // true // Object methods Object.keys(person) // ['name', 'email', 'greet'] Object.values(person) // ['Alice', 'alice@example.com', [Function]] Object.entries(person) // [['name', 'Alice'], ...]
Destructuring Objects
const person = { name: 'Alice', age: 30, city: 'NYC' }; // Basic destructuring const { name, age } = person; // Rename variables const { name: userName, age: userAge } = person; // Default values const { name, country = 'USA' } = person; // Nested destructuring const user = { profile: { name: 'Bob' } }; const { profile: { name } } = user;
Arrays
// Create array const arr = [1, 2, 3]; const empty = []; // Access elements arr[0] // 1 (first) arr[arr.length - 1] // 3 (last) arr.at(-1) // 3 (last, modern) // Modify arr.push(4) // Add to end: [1, 2, 3, 4] arr.pop() // Remove from end: returns 4 arr.unshift(0) // Add to start: [0, 1, 2, 3] arr.shift() // Remove from start: returns 0 // Slice (returns new array) arr.slice(1, 3) // [2, 3] (index 1 to 2) // Splice (mutates array) arr.splice(1, 2, 'a', 'b') // Remove 2 items at index 1, add 'a', 'b' // Join/Split [1, 2, 3].join('-') // '1-2-3' 'a,b,c'.split(',') // ['a', 'b', 'c']
Array Methods (Functional)
const numbers = [1, 2, 3, 4, 5]; // map: transform each element numbers.map(x => x * 2) // [2, 4, 6, 8, 10] // filter: keep matching elements numbers.filter(x => x % 2 === 0) // [2, 4] // reduce: combine to single value numbers.reduce((sum, x) => sum + x, 0) // 15 // find: first matching element numbers.find(x => x > 3) // 4 // findIndex: index of first match numbers.findIndex(x => x > 3) // 3 // some: at least one matches numbers.some(x => x > 3) // true // every: all match numbers.every(x => x > 0) // true // forEach: iterate (no return value) numbers.forEach(x => console.log(x)); // includes: check if contains value numbers.includes(3) // true // sort: sorts in place (mutates!) [3, 1, 2].sort() // [1, 2, 3] [3, 1, 2].sort((a, b) => b - a) // [3, 2, 1] (descending) // reverse: reverses in place [1, 2, 3].reverse() // [3, 2, 1]
Destructuring Arrays
const arr = [1, 2, 3, 4, 5]; // Basic destructuring const [first, second] = arr; // first=1, second=2 // Skip elements const [first, , third] = arr; // first=1, third=3 // Rest pattern const [first, ...rest] = arr; // first=1, rest=[2,3,4,5] // Swap variables [a, b] = [b, a];
Classes
Basic Class
class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { return `Hi, I'm ${this.name}`; } haveBirthday() { this.age++; } } const alice = new Person('Alice', 30); alice.greet(); // "Hi, I'm Alice"
Inheritance
class Student extends Person { constructor(name, age, grade) { super(name, age); // Call parent constructor this.grade = grade; } study() { return `${this.name} is studying`; } // Override parent method greet() { return `${super.greet()}, I'm in grade ${this.grade}`; } } const bob = new Student('Bob', 16, 10); bob.greet(); // "Hi, I'm Bob, I'm in grade 10" bob.study(); // "Bob is studying"
Static Methods & Private Fields
class MathUtils { // Static method (called on class, not instance) static square(x) { return x * x; } } MathUtils.square(5); // 25 class BankAccount { // Private field (# prefix) #balance = 0; deposit(amount) { this.#balance += amount; } getBalance() { return this.#balance; } }
Getters & Setters
class Rectangle { constructor(width, height) { this.width = width; this.height = height; } get area() { return this.width * this.height; } set area(value) { this.width = Math.sqrt(value); this.height = Math.sqrt(value); } } const rect = new Rectangle(10, 5); console.log(rect.area); // 50 (getter) rect.area = 100; // setter
Asynchronous JavaScript
Promises
// Creating a promise const promise = new Promise((resolve, reject) => { const success = true; if (success) { resolve('Done!'); } else { reject('Failed!'); } }); // Using promises promise .then(result => console.log(result)) .catch(error => console.error(error)) .finally(() => console.log('Cleanup')); // Chaining promises fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));
Async/Await
// Async function (always returns a promise) async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; } catch (error) { console.error('Error:', error); } } // Arrow async function const getData = async () => { const data = await fetchData(); return data; }; // Use async function fetchData().then(data => console.log(data));
Promise Combinators
// Promise.all: wait for all (fails if any fails) const [users, posts] = await Promise.all([ fetch('/api/users').then(r => r.json()), fetch('/api/posts').then(r => r.json()) ]); // Promise.allSettled: wait for all (never fails) const results = await Promise.allSettled([promise1, promise2]); // Promise.race: first to finish (resolve or reject) const fastest = await Promise.race([promise1, promise2]); // Promise.any: first to resolve (ignores rejections) const first = await Promise.any([promise1, promise2]);
setTimeout & setInterval
// Delay execution setTimeout(() => { console.log('Runs after 1 second'); }, 1000); // Repeat execution const intervalId = setInterval(() => { console.log('Runs every 2 seconds'); }, 2000); // Cancel interval clearInterval(intervalId); // Promise-based delay const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); await delay(1000);
Modules (ES6)
Exporting
// Named exports export const add = (a, b) => a + b; export const subtract = (a, b) => a - b; // Export list const multiply = (a, b) => a * b; const divide = (a, b) => a / b; export { multiply, divide }; // Default export (one per file) export default function greet(name) { return `Hello, ${name}!`; } // Named + default export export default class User { } export const VERSION = '1.0.0';
Importing
// Import named exports import { add, subtract } from './math.js'; // Import all as namespace import * as math from './math.js'; math.add(1, 2); // Import default export import greet from './greet.js'; // Import default + named import User, { VERSION } from './user.js'; // Rename imports import { add as sum } from './math.js'; // Dynamic import (returns promise) const module = await import('./module.js');
DOM Manipulation
Selecting Elements
// Select single element const el = document.getElementById('myId'); const el = document.querySelector('.myClass'); // CSS selector const el = document.querySelector('div > p:first-child'); // Select multiple elements const els = document.getElementsByClassName('myClass'); const els = document.getElementsByTagName('p'); const els = document.querySelectorAll('.myClass'); // NodeList
Modifying Elements
// Content el.textContent = 'New text'; // text only el.innerHTML = '<b>Bold</b>'; // HTML content // Attributes el.getAttribute('href'); el.setAttribute('href', 'https://...'); el.removeAttribute('disabled'); el.hasAttribute('disabled'); // Direct property access (preferred) el.href = 'https://...'; el.disabled = true; // Classes el.classList.add('active'); el.classList.remove('hidden'); el.classList.toggle('visible'); el.classList.contains('active'); // true/false // Styles el.style.color = 'red'; el.style.backgroundColor = 'blue'; // camelCase!
Creating & Removing Elements
// Create element const div = document.createElement('div'); div.textContent = 'Hello'; div.classList.add('box'); // Add to DOM parent.appendChild(div); // Add to end parent.insertBefore(div, sibling); // Insert before sibling parent.prepend(div); // Add to start parent.append(div); // Add to end (modern) // Remove from DOM el.remove(); // Remove element parent.removeChild(el); // Old way
Event Listeners
// Add event listener button.addEventListener('click', (event) => { console.log('Clicked!', event); }); // Common events el.addEventListener('click', handler); el.addEventListener('dblclick', handler); el.addEventListener('mouseenter', handler); el.addEventListener('mouseleave', handler); el.addEventListener('keydown', handler); el.addEventListener('keyup', handler); el.addEventListener('submit', handler); el.addEventListener('input', handler); el.addEventListener('change', handler); // Event object function handleClick(event) { event.preventDefault(); // Stop default action event.stopPropagation(); // Stop bubbling event.target; // Element that triggered event event.currentTarget; // Element with listener } // Remove event listener (needs same function reference) el.removeEventListener('click', handler);
Forms
// Get form values const input = document.querySelector('input[name="email"]'); const value = input.value; // Handle form submit form.addEventListener('submit', (e) => { e.preventDefault(); const formData = new FormData(form); const email = formData.get('email'); // Send to server... });
Modern JavaScript Features
Optional Chaining (?.)
// Safe property access (returns undefined if null/undefined) const city = user?.address?.city; // Safe function call const result = obj.method?.(); // Safe array access const first = arr?.[0];
Nullish Coalescing (??)
// Use default only if null or undefined (not 0, '', false) const value = userInput ?? 'default'; // vs OR operator (treats 0, '', false as falsy) const value = userInput || 'default';
Logical Assignment
// Assign only if falsy x ||= 10; // x = x || 10 // Assign only if truthy x &&= 10; // x = x && 10 // Assign only if nullish x ??= 10; // x = x ?? 10
Array Methods (Modern)
// at: negative indexing arr.at(-1) // Last element // flat: flatten nested arrays [[1, 2], [3, 4]].flat() // [1, 2, 3, 4] // flatMap: map + flat [1, 2].flatMap(x => [x, x * 2]) // [1, 2, 2, 4] // findLast: find from end arr.findLast(x => x > 3) // toSorted: non-mutating sort (returns new array) const sorted = arr.toSorted() // toReversed: non-mutating reverse const reversed = arr.toReversed()
Object Methods (Modern)
// Object.fromEntries: array to object const obj = Object.fromEntries([['a', 1], ['b', 2]]); // structuredClone: deep clone const clone = structuredClone(obj); // Object.hasOwn: safer hasOwnProperty Object.hasOwn(obj, 'key')
String Methods (Modern)
// replaceAll: replace all occurrences 'hello'.replaceAll('l', 'L') // 'heLLo' // trimStart/trimEnd: trim specific sides ' hello '.trimStart() // 'hello ' ' hello '.trimEnd() // ' hello' // padStart/padEnd: add padding '5'.padStart(3, '0') // '005' '5'.padEnd(3, '0') // '500'
Try/Catch & Error Handling
// Basic try/catch try { throw new Error('Something went wrong'); } catch (error) { console.error(error.message); } finally { console.log('Always runs'); } // Custom error class ValidationError extends Error { constructor(message) { super(message); this.name = 'ValidationError'; } }
JSON
// Parse JSON string const obj = JSON.parse('{"name":"Alice","age":30}'); // Stringify object const json = JSON.stringify({ name: 'Alice', age: 30 }); // Pretty print (indent with 2 spaces) const pretty = JSON.stringify(obj, null, 2);
Use strict mode (
'use strict';) at the top of files for better error checking. Modern modules use strict mode by default.