JavaScript
Updated: May 21, 2026Categories: Frontend, Backend, Languages, Web
Printed from:
Complete JavaScript Cheatsheet
Targets modern JavaScript (ES2024+) running on Node 20+ / current browsers. Focuses on what you actually use day-to-day; for the type layer see TypeScript.
Table of Contents
- Variables & Types
- Strings
- Numbers, Math, Dates
- Arrays
- Objects
- Destructuring & Spread
- Functions
- Control Flow
- Classes
- Modules
- Promises & Async/Await
- Iterators & Generators
- Errors
- Map, Set, WeakMap, WeakSet
- JSON
- Regex
- DOM Quick Reference
- Fetch & Networking
- Node.js Essentials
- Tooling
- Quick Reference
Variables & Types
js
1234567891011121314151617181920212223242526272829303132333435363738394041const name = "Ada"; // immutable binding (preferred)
let count = 0; // reassignable
// var // function-scoped, hoisted — avoid
// 7 primitive types + object
typeof "x" // "string"
typeof 1 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof undefined // "undefined"
typeof Symbol("a") // "symbol"
typeof null // "object" (historical bug)
typeof {} // "object"
typeof [] // "object"
typeof (() => {}) // "function"
// Coercion quirks (memorise the ones that bite)
"5" + 1 // "51" (string concatenation)
"5" - 1 // 4 (numeric)
+"42" // 42
Number("") // 0
[] == false // true
null == undefined // true
null === undefined // false
// Equality
=== // strict, no coercion (use this)
== // loose, coerces (avoid)
// Nullish vs falsy
const x = a ?? "default"; // a is null/undefined → "default"
const y = a || "default"; // a is any falsy (0, "", false) → "default"
obj?.user?.name // optional chaining
obj?.["key"]
fn?.()
// Logical assignment (ES2021)
a ||= b; // a = a || b
a ??= b; // a = a ?? b
a &&= b; // a = a && b
Strings
js
123456789101112131415161718192021222324252627const s = "hello";
s.length
s.toUpperCase()
s.toLowerCase()
s.trim() s.trimStart() s.trimEnd()
s.startsWith("he") s.endsWith("lo") s.includes("ll")
s.indexOf("l") s.lastIndexOf("l")
s.replace("l", "L") // first occurrence
s.replaceAll("l", "L")
s.split("") // ["h","e","l","l","o"]
s.slice(1, 3) // "el"
s.repeat(3)
s.padStart(10, "0")
s.padEnd(10, " ")
s.at(-1) // "o" (negative index)
// Template literals
`Hi, ${name}, ${1 + 2}`
`multi
line`
String.raw`\n is two chars: ${"!"}`
// Char codes / Unicode
"A".charCodeAt(0) // 65
String.fromCharCode(65) // "A"
"🙂".codePointAt(0) // 128578
String.fromCodePoint(128578)
Numbers, Math, Dates
js
12345678910111213141516171819202122232425262728293031323334353637// Numbers
Number.MAX_SAFE_INTEGER // 2^53 - 1
Number.isInteger(1)
Number.isNaN(NaN)
Number.parseFloat("3.14abc") // 3.14
Number.parseInt("0xff", 16) // 255
(1.005).toFixed(2) // "1.00" (beware float)
(1234567).toLocaleString("en-US") // "1,234,567"
// BigInt — for integers beyond Number safe range
const big = 9007199254740993n;
big + 1n
// Math
Math.abs(-3) Math.sign(-3)
Math.min(...arr) Math.max(...arr)
Math.floor(1.7) Math.ceil(1.2) Math.round(1.5) Math.trunc(1.7)
Math.pow(2, 10) // or 2 ** 10
Math.sqrt(2) Math.cbrt(27)
Math.random() // [0, 1)
Math.PI Math.E
// Dates (built-in is messy; use Temporal when available)
const d = new Date();
d.toISOString() // "2026-05-20T..."
d.getTime() // ms since epoch
Date.now()
new Date("2024-01-01T00:00:00Z")
// Intl
new Intl.NumberFormat("fr-FR").format(1234567.89)
new Intl.DateTimeFormat("en-GB", { dateStyle: "long" }).format(d)
new Intl.RelativeTimeFormat("en").format(-3, "day") // "3 days ago"
// Temporal (stage 3 / coming) — use polyfill today: @js-temporal/polyfill
// Temporal.Now.plainDateISO().toString()
Arrays
js
12345678910111213141516171819202122232425262728293031323334353637383940414243444546const a = [1, 2, 3];
a.length
a.push(4) a.pop()
a.unshift(0) a.shift()
a.slice(1, 3) // non-mutating
a.splice(1, 2) // mutating: remove
a.splice(1, 0, "x", "y") // mutating: insert
a.concat([4, 5])
a.indexOf(2) a.lastIndexOf(2)
a.includes(2)
a.find(x => x > 1)
a.findIndex(x => x > 1)
a.findLast(x => x > 0) // ES2023
a.some(x => x > 2)
a.every(x => x > 0)
a.map(x => x * 2)
a.filter(x => x % 2)
a.reduce((acc, x) => acc + x, 0)
a.reduceRight(...)
a.flat() a.flat(2)
a.flatMap(x => [x, x])
a.join(",")
a.sort() // mutating, lexicographic by default
a.sort((x, y) => x - y) // numeric
a.reverse() // mutating
// Non-mutating equivalents (ES2023)
a.toSorted((x, y) => x - y)
a.toReversed()
a.toSpliced(1, 2)
a.with(0, 99) // replace index 0
// Iteration
for (const x of a) {}
a.forEach((x, i) => {});
a.entries() a.keys() a.values()
[...a] // shallow copy
Array.from("abc") // ["a","b","c"]
Array.from({ length: 3 }, (_, i) => i) // [0, 1, 2]
Array.of(1, 2, 3)
Array.isArray(a)
// Group (ES2024)
Object.groupBy(arr, x => x.type)
Map.groupBy(arr, x => x.type)
Objects
js
123456789101112131415161718192021222324252627282930313233343536373839404142const u = { id: 1, name: "Ada", "x-y": true };
// Access
u.id
u["x-y"]
u?.deep?.path
// Set / delete
u.email = "x@y.z";
delete u.email;
// Iterate
Object.keys(u)
Object.values(u)
Object.entries(u)
Object.fromEntries([["a", 1], ["b", 2]])
// Copy / merge
{ ...u, age: 30 } // shallow copy + override
Object.assign({}, u, { age: 30 })
// Inspect
"id" in u
u.hasOwnProperty("id") // (prefer Object.hasOwn)
Object.hasOwn(u, "id")
// Freeze / seal
Object.freeze(u) // immutable (shallow)
Object.isFrozen(u)
Object.seal(u) // no add/remove, can modify
// Computed keys + shorthand + methods
const key = "x";
const obj = { [key]: 1, name, greet() { return name; } };
// Property descriptors
Object.defineProperty(u, "x", { value: 1, writable: false, enumerable: true, configurable: false });
Object.getOwnPropertyDescriptors(u)
// Structured cloning (deep copy, ES2022 on browsers + Node 17+)
const deep = structuredClone(u);
Destructuring & Spread
js
123456789101112131415161718// Array
const [a, b, ...rest] = [1, 2, 3, 4];
const [, , c] = [1, 2, 3]; // skip
const [x = 10] = []; // default
// Object
const { id, name: n, email = "" } = user; // rename + default
const { a: { b } } = obj; // nested
// In function signatures
function fn({ id, name }) {}
function arr([x, y]) {}
// Spread
const merged = { ...a, ...b };
const cloned = [...arr];
fn(...args);
Functions
js
12345678910111213141516171819202122232425function add(a, b) { return a + b; }
// Arrow — no `this`, no `arguments`, no `prototype`
const inc = (x) => x + 1;
const obj = { name: "Ada", greet: () => this.name }; // ⚠️ this is wrong here
// Default + rest
function f(a, b = 2, ...rest) {}
// IIFE
(() => { /* … */ })();
// `this` and binding
const bound = fn.bind(ctx, arg1);
fn.call(ctx, arg1, arg2);
fn.apply(ctx, [arg1, arg2]);
// Currying & partial
const partial = (f, ...a) => (...b) => f(...a, ...b);
// Recursion / tail calls (no TCO in V8 — beware)
// Named function expression
const f = function self(n) { return n <= 1 ? 1 : n * self(n - 1); };
Control Flow
js
12345678910111213141516171819202122232425if (a) {} else if (b) {} else {}
// Ternary / nullish
const v = a ?? "x";
const w = a > 0 ? "+" : "-";
// switch
switch (kind) {
case "a": case "b": doAB(); break;
case "c": doC(); break;
default: throw new Error("unknown");
}
// Loops
for (let i = 0; i < 10; i++) {}
for (const x of arr) {}
for (const [k, v] of Object.entries(obj)) {}
while (cond) {}
do { /* … */ } while (cond);
// Labels (rare)
outer: for (...) { for (...) { break outer; } }
// `for...in` iterates KEYS of an object — usually not what you want for arrays
Classes
js
1234567891011121314151617181920212223242526272829303132class Animal {
static kingdom = "Animalia"; // class field
#secret = 42; // private field
constructor(name) {
this.name = name;
}
greet() { return `Hi, I'm ${this.name}`; }
get label() { return `[${this.name}]`; }
set label(v) { this.name = v.replace(/[\[\]]/g, ""); }
static of(name) { return new Animal(name); }
}
class Dog extends Animal {
constructor(name) {
super(name);
}
bark() { return "woof"; }
}
const d = new Dog("Rex");
d instanceof Dog
d instanceof Animal
// Symbol.iterator
class Range {
constructor(from, to) { this.from = from; this.to = to; }
*[Symbol.iterator]() {
for (let i = this.from; i <= this.to; i++) yield i;
}
}
for (const n of new Range(1, 3)) console.log(n);
Modules
js
12345678910111213141516171819// ESM (the default in modern code)
export const x = 1;
export function add(a, b) { return a + b; }
export default class App {}
import App, { add, x } from "./mod.js";
import * as M from "./mod.js";
import { add as plus } from "./mod.js";
// Dynamic import (returns a promise)
const mod = await import("./mod.js");
// Re-export
export { add } from "./mod.js";
export * from "./mod.js";
// JSON modules (Node 22+ / browsers)
import data from "./data.json" with { type: "json" };
In Node, "type": "module" in package.json enables ESM. .cjs / .mjs extensions override.
Promises & Async/Await
js
123456789101112131415161718192021222324252627282930313233343536373839// Promise basics
const p = fetch(url)
.then(r => r.json())
.then(data => use(data))
.catch(err => log(err))
.finally(() => done());
// async / await
async function main() {
try {
const r = await fetch(url);
const data = await r.json();
return data;
} catch (e) {
handle(e);
} finally {
cleanup();
}
}
// Combinators
await Promise.all([p1, p2, p3]); // fail-fast
await Promise.allSettled([p1, p2]); // wait for all, never throws
await Promise.race([p1, p2]); // first to settle
await Promise.any([p1, p2]); // first to fulfill
// Create
new Promise((resolve, reject) => { /* … */ });
Promise.resolve(1);
Promise.reject(new Error("x"));
// AbortController (cancellation)
const c = new AbortController();
fetch(url, { signal: c.signal });
setTimeout(() => c.abort(), 5000);
// Top-level await (ESM modules only)
const data = await fetchData();
Iterators & Generators
js
123456789101112131415161718192021// Iterator protocol: an object with .next() returning { value, done }
const iter = arr[Symbol.iterator]();
iter.next(); // { value: 1, done: false }
// Generators
function* range(n) {
for (let i = 0; i < n; i++) yield i;
}
for (const i of range(3)) console.log(i);
// Delegating
function* outer() { yield* inner(); }
// Async iteration
async function* lines(stream) {
for await (const chunk of stream) {
yield* chunk.split("\n");
}
}
for await (const line of lines(stdin)) {}
Errors
js
12345678910111213141516171819class HttpError extends Error {
constructor(message, { status, cause } = {}) {
super(message, { cause });
this.name = "HttpError";
this.status = status;
}
}
try {
throw new HttpError("not found", { status: 404 });
} catch (e) {
if (e instanceof HttpError) console.log(e.status);
console.log(e.cause); // optional chained cause (ES2022)
}
// AggregateError (from Promise.any)
try { await Promise.any([]); }
catch (e) { console.log(e.errors); }
Map, Set, WeakMap, WeakSet
js
12345678910111213141516171819202122232425const m = new Map();
m.set("a", 1).set("b", 2);
m.get("a") m.has("a") m.delete("a")
m.size
for (const [k, v] of m) {}
new Map([["a", 1], ["b", 2]])
Object.fromEntries(m)
const s = new Set([1, 2, 2, 3]); // {1,2,3}
s.add(4) s.delete(2) s.has(3)
[...s]
// Set ops (ES2024)
s.union(s2)
s.intersection(s2)
s.difference(s2)
s.symmetricDifference(s2)
s.isSubsetOf(s2)
s.isSupersetOf(s2)
s.isDisjointFrom(s2)
// Weak* — keys held weakly, not iterable
const w = new WeakMap();
const ws = new WeakSet();
JSON
js
123456JSON.stringify(obj)
JSON.stringify(obj, null, 2) // pretty
JSON.stringify(obj, (k, v) => v ?? undefined) // replacer
JSON.parse(text)
JSON.parse(text, (k, v) => k === "date" ? new Date(v) : v)
Regex
js
1234567891011121314const re = /^\d{3}-\d{4}$/;
const re2 = new RegExp("^\\d+$", "i");
re.test("555-1234") // true
"abc123".match(/\d+/) // ["123"]
"abc123 def456".matchAll(/\d+/g) // iterator of matches
"a,b,c".split(/,/)
"abc".replace(/b/, "B")
"a1b2c3".replace(/\d/g, "*")
"a1b2".replace(/(\d)/g, (_m, d) => d * 2)
// Named groups + lookbehind (ES2018+)
/(?<year>\d{4})-(?<month>\d{2})/.exec("2026-05").groups
/(?<=\$)\d+/.exec("price: $42")
Flags: g global, i ignore case, m multiline, s dotAll, u unicode, y sticky, d indices.
DOM Quick Reference
js
12345678910111213141516171819202122232425262728293031323334document.querySelector(".btn");
document.querySelectorAll("li");
const el = document.getElementById("id");
el.textContent = "x";
el.innerHTML = "<b>x</b>"; // ⚠️ XSS risk with untrusted input
el.classList.add("on") .remove("off") .toggle("x") .contains("y")
el.setAttribute("data-id", 1) el.getAttribute("data-id")
el.dataset.id = 1;
el.style.color = "red";
el.append(child) el.prepend(child) el.remove()
el.addEventListener("click", (e) => { e.preventDefault(); });
el.removeEventListener("click", handler);
// Delegation
list.addEventListener("click", e => {
const li = e.target.closest("li");
if (li) console.log(li.dataset.id);
});
// Creating
const div = document.createElement("div");
div.append("hello");
// Forms
form.elements.name.value
new FormData(form) // works with fetch
// Observers
new IntersectionObserver((entries) => {}).observe(el);
new MutationObserver((muts) => {}).observe(el, { childList: true });
new ResizeObserver((entries) => {}).observe(el);
Fetch & Networking
js
1234567891011121314151617181920212223const res = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Ada" }),
signal: AbortSignal.timeout(5000), // ES2024
credentials: "include",
cache: "no-store",
});
if (!res.ok) throw new Error(res.statusText);
const data = await res.json(); // or .text(), .blob(), .arrayBuffer(), .formData()
// Streams
for await (const chunk of res.body) console.log(chunk);
// EventSource (Server-Sent Events)
const es = new EventSource("/events");
es.onmessage = e => console.log(e.data);
// WebSocket
const ws = new WebSocket("wss://example.com");
ws.onopen = () => ws.send("hi");
ws.onmessage = e => console.log(e.data);
Node.js Essentials
js
123456789101112131415161718192021222324252627282930// Built-in modules (ESM with node: prefix is recommended)
import fs from "node:fs/promises";
import path from "node:path";
import os from "node:os";
import { fileURLToPath } from "node:url";
import { setTimeout as wait } from "node:timers/promises";
// Files
const text = await fs.readFile("./a.txt", "utf8");
await fs.writeFile("./b.txt", text);
for await (const dirent of await fs.opendir("./")) console.log(dirent.name);
// Path
path.join(__dirname, "data");
path.resolve("./a/b");
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Process
process.env.NODE_ENV
process.argv // ["node", "script.js", ...args]
process.exit(1)
process.on("SIGTERM", () => {});
// Stdin / streams
for await (const line of process.stdin) {}
// HTTP server (one-liner via Bun / built-in)
import { createServer } from "node:http";
createServer((req, res) => res.end("ok")).listen(3000);
Modern alternatives: Bun, Deno — many built-ins (Bun.serve, Deno.serve, Deno.readTextFile) are simpler.
Tooling
Bash
1234567891011121314151617181920212223# Run TS / JS directly
node script.js
node --watch script.js
node --import tsx script.ts # Node 22+
bun run script.ts
deno run --allow-net script.ts
# Format / lint
pnpm add -D prettier eslint
pnpm exec prettier --write .
pnpm exec eslint --fix .
# Test
node --test # built-in test runner (Node 20+)
pnpm add -D vitest # or vitest / bun test
pnpm exec vitest
# Build
pnpm add -D esbuild # or vite, tsup, rollup, swc, parcel
# Package managers
npm pnpm yarn bun
Quick Reference
js
123456789101112131415161718192021222324252627282930313233// Variables / nullish
const x = a ?? b;
const y = a?.b?.c;
a ||= b; a ??= b; a &&= b;
// Arrays
arr.map / filter / reduce / find / some / every / flatMap
arr.includes(x) arr.at(-1)
arr.toSorted() arr.toReversed() arr.with(i, v)
// Objects
{ ...a, ...b }
Object.keys / values / entries / fromEntries / hasOwn / groupBy
structuredClone(obj)
// Async
await Promise.all / allSettled / race / any
new AbortController()
top-level await (in ESM)
// Iteration
for (const x of iter) {}
for await (const x of asyncIter) {}
function* yield yield*
// Patterns
?? ?. ?.()
template literals destructuring spread
// Modules
import / export / import.meta / dynamic import()
"type": "module" in package.json
Tip: in 2025+, default to ESM,
const+ arrow functions,??over||for defaults,?.over manual null guards,awaitover.thenchains, and TypeScript the moment a project grows past a single file.
Continue Learning
Discover more cheatsheets to boost your productivity