Every essential JavaScript concept in one place — variables, functions, arrays, objects, DOM, async/await, ES6+ and more. Curated for beginners to advanced developers.
Declare variables with let,
const
and var,
understand JavaScript's 8 primitive types and type coercion.
// var — function-scoped, hoisted var name = 'Alice'; // let — block-scoped, reassignable let age = 30; age = 31; // ✓ OK // const — block-scoped, no reassign const PI = 3.14159; // PI = 3; ✗ TypeError // const objects are mutable! const user = { name: 'Bob' }; user.name = 'Carol'; // ✓ OK // user = {}; ✗ TypeError // Temporal Dead Zone (TDZ) // console.log(x); // ReferenceError let x = 5;
typeof 'hello' // "string" typeof 42 // "number" typeof 3.14 // "number" typeof true // "boolean" typeof undefined // "undefined" typeof null // "object" ← JS quirk typeof 42n // "bigint" typeof Symbol() // "symbol" typeof {} // "object" typeof [] // "object" ← array typeof function(){} // "function" // Type conversion Number('42') // 42 String(42) // "42" Boolean(0) // false parseInt('10px') // 10 parseFloat('3.5') // 3.5
// == vs === (always prefer ===) 1 == '1' // true (coercion) 1 === '1' // false (strict) // Logical operators true && false // false true || false // true !true // false // Nullish coalescing (??) — ES2020 const val = null ?? 'default'; // "default" const v2 = 0 ?? 'default'; // 0 // Optional chaining (?.) — ES2020 const city = user?.address?.city; // Logical assignment a ||= 'default' // a = a || 'default' b &&= 42 // b = b && 42 c ??= 'fallback' // c = c ?? 'fallback'
Declarations, expressions, arrow functions, closures, higher-order functions and the this keyword explained.
// Declaration — hoisted function greet(name) { return `Hello, ${name}!`; } // Expression — not hoisted const greet = function(name) { return `Hello, ${name}!`; }; // Arrow function const greet = name => `Hello, ${name}!`; // IIFE — Immediately Invoked (function() { console.log('runs now!'); })(); // Default parameters function add(a, b = 0) { return a + b; }
// Closure: inner fn accesses outer scope function makeCounter() { let count = 0; return { increment: () => ++count, decrement: () => --count, value: () => count }; } const ctr = makeCounter(); ctr.increment(); // 1 // Rest parameters function sum(...nums) { return nums.reduce((a,b) => a+b, 0); } sum(1,2,3); // 6 // Higher-order function function multiply(factor) { return n => n * factor; } const double = multiply(2); double(5); // 10
const person = { name: 'Alice', greet() { console.log(this.name); // 'Alice' } }; // Arrow fn: this = enclosing scope const obj = { val: 42, get: () => this.val // undefined! }; // call — invoke with explicit this greet.call(person, arg1); // apply — same but args as array greet.apply(person, [arg1]); // bind — returns new function const boundGreet = greet.bind(person); boundGreet();
Create, modify, iterate and transform arrays using powerful built-in methods — map, filter, reduce, and beyond.
const arr = [1, 2, 3]; const arr2 = new Array(3).fill(0); // [0,0,0] const arr3 = Array.from('abc'); // ['a','b','c'] const arr4 = Array.from({length:5}, (_,i) => i); // Mutating methods arr.push(4); // add end → [1,2,3,4] arr.pop(); // remove end → 4 arr.unshift(0); // add start arr.shift(); // remove start arr.splice(1,1); // remove at index arr.splice(1,0,99); // insert at index arr.sort((a,b) => a-b); // ascending arr.reverse();
const nums = [1,2,3,4,5]; // map — transform every element nums.map(n => n * 2); // [2, 4, 6, 8, 10] // filter — keep matching elements nums.filter(n => n % 2 === 0); // [2, 4] // reduce — accumulate to single value nums.reduce((acc, n) => acc+n, 0); // 15 // find / findIndex nums.find(n => n > 3); // 4 nums.findIndex(n => n===3); // 2 // some / every nums.some(n => n>4); // true nums.every(n => n>0); // true // flat / flatMap [1,[2,[3]]].flat(2); // [1,2,3]
const a = [1,2,3,4,5]; // slice — non-mutating copy a.slice(1,3); // [2, 3] a.slice(-2); // [4, 5] // includes / indexOf a.includes(3); // true a.indexOf(3); // 2 // concat — merge arrays [1,2].concat([3,4]); // [1,2,3,4] // join — to string a.join(' - '); // "1 - 2 - 3 - 4 - 5" // Spread operator const b = [...a, 6, 7]; const c = [...a, ...b]; // merge // Destructuring const [first, second, ...rest] = a;
Create, read, modify and clone objects — destructuring, spread, computed keys, Map and Set.
const user = { name: 'Alice', age: 30, greet() { return `Hi, I'm ${this.name}` } }; // Access user.name // dot notation user['name'] // bracket notation // Add / Modify / Delete user.email = 'a@b.com'; user.age = 31; delete user.email; // Check property exists 'name' in user // true user.hasOwnProperty('age') // true // Iterate Object.keys(user) // ['name','age'] Object.values(user) // ['Alice', 30] Object.entries(user) // [['name','Alice'],…]
// Destructuring with rename & default const { name: n, age = 18, ...rest } = user; // Nested destructuring const { address: { city } } = user; // Function parameter destructuring function show({ name, age = 0 }) { console.log(name, age); } // Spread — shallow clone const copy = { ...user }; const merged = { ...user, ...extra }; // Deep clone const deep = structuredClone(user); // Computed property keys const key = 'name'; const obj = { [key]: 'Alice' }; // Object.freeze — immutable Object.freeze(user);
// Map — any key type, ordered const map = new Map(); map.set('name', 'Alice'); map.set(obj, 42); // object as key map.get('name'); // 'Alice' map.has('name'); // true map.delete('name'); map.size; // 1 // Iterate Map for (const [k, v] of map) {/*…*/} // Set — unique values const set = new Set([1,2,2,3]); // Set {1, 2, 3} set.add(4); set.has(2); // true set.delete(2); // Remove duplicates from array const unique = [...new Set(arr)];
Select, create, modify and remove DOM elements — events, dataset, classList, and traversal.
// Modern — CSS selector syntax const el = document.querySelector('.card'); const els = document.querySelectorAll('li'); // Legacy document.getElementById('app'); document.getElementsByClassName('btn'); document.getElementsByTagName('div'); // Traversal el.parentElement el.children // HTMLCollection el.firstElementChild el.lastElementChild el.nextElementSibling el.previousElementSibling el.closest('.parent') // walk up tree
// Content el.textContent = 'Hello'; // safe el.innerHTML = '<b>Hi</b>'; // Attributes el.setAttribute('data-id', 5); el.getAttribute('href'); el.removeAttribute('disabled'); // Classes el.classList.add('active'); el.classList.remove('active'); el.classList.toggle('open'); el.classList.contains('btn'); // Inline styles el.style.color = 'red'; el.style.display = 'none'; // Create & append const div = document.createElement('div'); div.textContent = 'New!'; document.body.appendChild(div); el.insertAdjacentHTML('beforeend', '…');
// Add event listener btn.addEventListener('click', handler); btn.removeEventListener('click', handler); // Event object el.addEventListener('click', e => { e.preventDefault(); // stop default e.stopPropagation(); // stop bubble console.log(e.target); // clicked element console.log(e.currentTarget); }); // Event delegation — efficient list.addEventListener('click', e => { if (e.target.matches('li')) {/*…*/} }); // Common events // click dblclick mouseover mouseout // keydown keyup keypress // input change submit focus blur // scroll resize DOMContentLoaded
Handle asynchronous operations cleanly with Promises, async/await and the Fetch API.
// Create a promise const p = new Promise((resolve, reject) => { if (ok) resolve(data); else reject(new Error('failed')); }); // Chain p .then(data => data.json()) .then(json => console.log(json)) .catch(err => console.error(err)) .finally(() => hideLoader()); // Parallel execution Promise.all([p1, p2]); // all or reject Promise.allSettled([p1,p2]); // all results Promise.race([p1, p2]); // first wins Promise.any([p1, p2]); // first fulfilled Promise.resolve(val); // wrap in promise Promise.reject(new Error()); // rejected
// async fn always returns a Promise async function fetchUser(id) { try { const res = await fetch(`/api/${id}`); if (!res.ok) throw new Error(res.status); const data = await res.json(); return data; } catch (err) { console.error(err); } } // Parallel with await const [u, p] = await Promise.all([ fetchUser(1), fetchPosts(1) ]); // Top-level await (ES modules) const data = await fetchUser(1); // Async arrow function const load = async () => { await … };
// GET request const res = await fetch('/api/users'); const json = await res.json(); // POST request const res = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Alice' }) }); // Response helpers res.ok // true if 200–299 res.status // 200 res.json() // parse JSON body res.text() // parse text res.blob() // binary data // AbortController — cancel request const ctrl = new AbortController(); fetch(url, { signal: ctrl.signal }); ctrl.abort(); // cancel
Template literals, destructuring, spread, generators, iterators, Symbols and more modern syntax sugar.
// Template literal const msg = `Hello, ${name}! You have ${count} messages.`; // Expression in template const price = `$${(cost * 1.1).toFixed(2)}`; // Tagged template function highlight(strings, ...vals) { return strings.reduce((acc, str, i) => acc + str + (vals[i] ? `<b>${vals[i]}</b>` : '') ); } highlight`Hello ${name}!`; // String methods (ES6+) 'abc'.startsWith('a'); // true 'abc'.endsWith('c'); // true 'abc'.includes('b'); // true 'ha'.repeat(3); // 'hahaha' '5'.padStart(3,'0'); // '005'
// Generator function function* range(start, end) { for (let i = start; i <= end; i++) yield i; } for (const n of range(1,5)) {/* 1 2 3 4 5 */} // Manual iterator const gen = range(1,3); gen.next(); // { value:1, done:false } gen.next(); // { value:2, done:false } // Iterable protocol const iterable = { [Symbol.iterator]() { let n = 0; return { next: () => n < 3 ? { value: n++, done: false } : { value: undefined, done: true } }; } }; for (const v of iterable) {/* 0 1 2 */}
// Optional chaining (?.) — ES2020 const zip = user?.addr?.zip; // Nullish coalescing (??) — ES2020 const port = config.port ?? 3000; // Array.at() — ES2022 [1,2,3].at(-1); // 3 // Object.hasOwn() — ES2022 Object.hasOwn(obj, 'key'); // structuredClone() — ES2022 const deep = structuredClone(nested); // Array grouping — ES2024 Object.groupBy(items, i => i.category); // Promise.withResolvers — ES2024 const { promise, resolve, reject } = Promise.withResolvers(); // Error.cause — ES2022 throw new Error('msg', { cause: err });
ES6 classes, inheritance, getters/setters, private fields, static members and the prototype chain.
class Animal { // Private field (ES2022) #sound = '...'; constructor(name, sound) { this.name = name; this.#sound = sound; } // Instance method speak() { return `${this.name} says ${this.#sound}`; } // Getter / Setter get info() { return this.name; } set info(v) { this.name = v; } // Static method (on the class) static create(n) { return new Animal(n); } } const dog = new Animal('Rex', 'Woof'); dog.speak(); // "Rex says Woof"
class Dog extends Animal { constructor(name, breed) { super(name, 'Woof'); // call parent this.breed = breed; } // Override parent method speak() { return super.speak() + '!'; } } // instanceof dog instanceof Dog; // true dog instanceof Animal; // true // Mixin pattern const Serializable = (Base) => class extends Base { toJSON() { return JSON.stringify(this); } }; class User extends Serializable(Animal) {} // Check prototype Object.getPrototypeOf(dog) === Dog.prototype;
Catch, throw and create custom errors — write robust code that handles failures gracefully.
try { const data = JSON.parse(input); risky(data); } catch (err) { if (err instanceof TypeError) { console.error('Type error:', err.message); } else { throw err; // re-throw unknown } } finally { cleanup(); // always runs } // Custom Error class class ValidationError extends Error { constructor(msg, field) { super(msg); this.name = 'ValidationError'; this.field = field; } } throw new ValidationError('Required', 'email');
| Error Type | When it occurs |
|---|---|
SyntaxError |
Invalid JS syntax at parse time |
TypeError |
Wrong type / null/undefined access |
ReferenceError |
Undefined variable used |
RangeError |
Number out of valid range |
URIError |
Bad encodeURI / decodeURI usage |
// Console utilities console.log(val); // info console.warn(val); // warning console.error(val); // error console.table(arr); // tabular data console.time('label'); // start timer console.timeEnd('label'); console.group('name'); // collapse group console.groupEnd(); console.assert(cond, 'msg');
Import, export, dynamic imports, and browser storage APIs for persisting data.
// math.js — named exports export const add = (a,b) => a+b; export const sub = (a,b) => a-b; export default function multiply(a,b) {return a*b} // app.js — import import multiply from './math.js'; import { add, sub } from './math.js'; import { add as sum } from './math.js'; import * as Math from './math.js'; // Re-export export { add } from './math.js'; // Dynamic import (lazy loading) const { add } = await import('./math.js'); // import.meta import.meta.url // current module URL import.meta.env // Vite/env vars
// localStorage — persists across sessions localStorage.setItem('user', JSON.stringify(obj)); const user = JSON.parse(localStorage.getItem('user')); localStorage.removeItem('user'); localStorage.clear(); // sessionStorage — cleared on tab close sessionStorage.setItem('token', tok); // Timers const id = setTimeout(() => {/*once*/}, 1000); clearTimeout(id); const iv = setInterval(() => {/*loop*/}, 500); clearInterval(iv); // requestAnimationFrame function animate() { // draw frame requestAnimationFrame(animate); } requestAnimationFrame(animate);
Test, search, match and replace text patterns with JavaScript's RegExp engine.
// Create regex const re1 = /hello/i; // literal const re2 = new RegExp('hello','i'); // Flags /pat/g // global — find all matches /pat/i // case-insensitive /pat/m // multiline (^ $ per line) /pat/s // dotAll (. matches \n) /pat/d // indices for matches // Character classes \d // digit [0-9] \w // word [a-zA-Z0-9_] \s // whitespace . // any char except \n \b // word boundary ^ // start of string $ // end of string // Quantifiers * // 0 or more + // 1 or more ? // 0 or 1 (optional) {3} // exactly 3 {2,5} // 2 to 5
const str = 'Hello World 123'; // test — boolean check /\d+/.test(str); // true // match — first or all matches str.match(/\d+/); // ['123'] str.match(/[a-z]+/gi); // all words // matchAll — iterator of all matches for (const m of str.matchAll(/\w+/g)) { console.log(m[0], m.index); } // replace str.replace(/World/, 'JS'); str.replaceAll(/l/g, 'L'); // Named capture groups const { groups: { y,m,d } } = '2024-06-01'.match( /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/ );
Proxy, Reflect, WeakRef, debounce, throttle, memoization and design patterns every JS dev should know.
// Proxy — intercept operations const handler = { get(target, key) { console.log(`Read: ${key}`); return Reflect.get(target, key); }, set(target, key, val) { if (typeof val !== 'number') throw new TypeError('Must be number'); return Reflect.set(target, key, val); } }; const p = new Proxy({}, handler); p.age = 30; // ok p.age = 'old'; // TypeError
// Debounce — wait until activity stops function debounce(fn, ms) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout( () => fn.apply(this, args), ms ); }; } const search = debounce(fetchResults, 300); input.addEventListener('input', search); // Throttle — fire at most once per interval function throttle(fn, ms) { let last = 0; return (...args) => { const now = Date.now(); if (now - last >= ms) { last = now; fn.apply(this, args); } }; }
// Memoize — cache results function memoize(fn) { const cache = new Map(); return (...args) => { const k = JSON.stringify(args); if (cache.has(k)) return cache.get(k); const res = fn(...args); cache.set(k, res); return res; }; } const fib = memoize(n => n <= 1 ? n : fib(n-1) + fib(n-2)); // WeakMap — GC-friendly private data const _private = new WeakMap(); class Safe { constructor(s) { _private.set(this, s); } getSecret() { return _private.get(this); } }
Keep learning with our other free developer references and guides — hand-crafted by K2Infocom.