const pi = 3.14★Block-scoped, can't be reassigned. Your default.let count = 0★Block-scoped and reassignable. Use when it changes.var x = 1avoidFunction-scoped, hoisted asundefined— legacy.const { a, b } = objDestructure fields into variables.const [x, y] = arrDestructure array elements by position.a = b = 5Chained assignment;constcan't be reassigned.x; let x = 1Reading alet/constbefore its line throws — the "temporal dead zone".
typeof v★"string" "number" "boolean" "undefined" "symbol" "bigint" "function" "object".typeof null === "object"A 1995 bug that can never be fixed. It's really null.Array.isArray(v)The right way to test for an array.Number.isNaN(v)Only true for the actualNaNvalue.Number.isInteger(v)Whole-number check, no coercion.v instanceof DateIs v built from this constructor / prototype chain?Number.isFinite(v)True only for a real finite number — no NaN, no ∞, no coercion.Object.prototype.toString.call(v)Robust tag:"[object Array]","[object Date]"…
const t = Boolean(v)★Falsy:0 "" null undefined NaN false. Everything else is truthy.1 + "2" === "12"★+with any string concatenates —Number(x)first to add."5" * 2 === 10- * / %coerce strings to numbers; only+is special.a == bcoerces==coerces:0 == ""is false but"" == falsetrue.null == undefinedThese two are loosely equal to each other and nothing else.x ?? fallbackES2020Coalesce for null/undefined only — keeps0and"".+v !!v `${v}`★Idioms to force a value to number / boolean / string.NaN === NaN // falseNaN is the only value not equal to itself — test withNumber.isNaN.
a === b a !== b★Strict equality — no type coercion. Always prefer.a == bcoercesLoose equality converts types first — surprising.&& || !Logical and / or / not.&&&||short-circuit & return an operand.a ?? b★ES2020Nullish coalescing — fall back only if a isnull/undefined.obj?.a?.m?.()★ES2020Optional chaining — stop & giveundefinedif any link is nullish.cond ? x : y★Ternary — the only operator taking 3 operands.a ??= b a ||= b a &&= bES2021Logical assignment — assign only if the test passes.2 ** 10Exponentiation → 1024. Same asMath.pow....arr ...obj★Spread — expand into a new array / object / call args.a + b a - b a * b a / b a % b★Arithmetic;%is remainder,+also concatenates strings.a++ --bIncrement / decrement; postfix returns the old value first."k" in obj delete o.kintests a key exists;deleteremoves a property.& | ^ ~ << >> >>>Bitwise on 32-bit ints;~~xfloors positives cheaply.
`hi ${name}, ${1+1}`★Template literal — interpolation + multi-line.s.includes("ab")★AlsostartsWith/endsWith→ boolean.s.slice(1, 4)Substring; negatives count from the end.s.replaceAll("a", "b")ES2021replacehits only the first; this hits all.s.split(",") arr.join(",")★String ⇄ array, the two directions.s.trim() .padStart(3,"0")Strip edges; left-pad (alsopadEnd).s.at(-1)ES2022Last char via negative index — cleaner thans[s.length-1].String(v) Number(s)Explicit conversion — clearer than+v/``+v.s.startsWith(x) .endsWith(x)★Boolean prefix / suffix tests.s.toUpperCase() .toLowerCase()Case conversion — returns a new string.s.repeat(3) .padEnd(5)Repeat n times; pad on the right to a width.s.indexOf(x) s.lengthPosition of a substring (−1 if absent); character count.
0.1 + 0.2 !== 0.3★Binary floats → 0.30000000000000004. Round before comparing.(3.14159).toFixed(2)→ "3.14" — note: returns a string.parseInt(s, 10) parseFloat(s)Parse leading number; always pass the radix.Math.round .floor .ceil .truncRounding family;truncjust drops the decimals.Math.max(...a) Math.random()Spread an array into max/min; random ∈ [0,1).1_000_000ES2021Numeric separators — digits only, purely cosmetic.9007199254740993nES2020BigInt— integers beyondNumber.MAX_SAFE_INTEGER.Math.abs .min .sqrt .pow .sign★The everyday Math helpers.(255).toString(16)Radix out →"ff";parseInt(s,16)reverses it.0xFF 0b1010 0o17Hex, binary, octal literals (= 255, 10, 15).Infinity -Infinity NaN1/0= ∞,0/0= NaN — and both are numbers.
new Date()★Now, as a Date object in local time.new Date(2024, 0, 15)★Month is 0-indexed —0= January,11= December.new Date("2024-03-01")ISO-string parse (UTC when the time is omitted).Date.now()★Milliseconds since the epoch — a cheap timestamp.d.getFullYear() .getMonth()Also getDate, getHours, getDay (0 = Sunday).d.toISOString()★"2024-03-01T00:00:00.000Z"— sortable, UTC.d.getTime() d2 - d1Epoch ms; subtracting two Dates gives a ms difference.d.toLocaleDateString()Locale display;Intl.DateTimeFormatfor full control.
[...a, ...b]★Merge / copy (shallow) via spread.Array.from({length:3}, (_,i)=>i)Build from iterable/length →[0,1,2].a.includes(x) a.indexOf(x)★Membership (bool) vs position (−1 if absent).a.find(x=>x>3) .findIndex()★First match by predicate — value or index.a.findLast() .findLastIndex()ES2023Same search, walking from the end.a.some(p) a.every(p)Any match? / all match? → boolean.a.at(-1)★ES2022Last element withouta[a.length-1].Array.of(1, 2) new Array(3)Build from args, or an empty length-n array to.fill.a.fill(0) a.lengthmutatesFill in place; settinglengthalso truncates.a.keys() .values() .entries()Iterators of indices / values /[i, v]pairs.
a.map(x=>x*2)★New array, one output per input.a.filter(x=>x>0)★New array, only elements passing the test.a.reduce((s,x)=>s+x, 0)★Fold to a single value; always pass the seed.a.forEach(x=>log(x))Side effects only — returnsundefined.a.flat() a.flatMap(f)Un-nest one level / map-then-flatten.a.sort((x,y)=>x-y)mutatesDefault sorts as strings! Pass a comparator for numbers.a.push .pop .splice .reversemutatesChange the array in place.a.toSorted() .toReversed()ES2023Copying twins — leave the original untouched.a.with(1, "x") .toSpliced()ES2023Copy with one index changed / spliced.a.slice(1, 3)★Copy a sub-range — non-mutating, unlikesplice.a.concat(b) a.join("-")Merge arrays; join elements into a string.a.shift() a.unshift(x)mutatesRemove / add at the front.a.reduceRight(fn, init)Fold from the right-hand end.
{ name, age, [key]: v }★Shorthand props + computed keys.{ ...base, id: 1 }★Spread-copy then override (shallow).Object.keys .values .entries(o)★Arrays of keys / values / [k,v] pairs to loop.Object.fromEntries(pairs)Rebuild an object from [k,v] pairs — inverse of entries.Object.hasOwn(o, "k")ES2022Safe own-property check; replaceshasOwnProperty.Object.freeze(o)Make shallowly immutable (silently ignores writes).Object.groupBy(arr, x=>x.type)ES2024Bucket items into an object keyed by the callback.Object.assign(dst, a, b)★Copy own enumerable props intodst(shallow).Object.create(proto)New object with an explicit prototype.Object.getPrototypeOf(o)Read the [[Prototype]];setPrototypeOfwrites it.Object.defineProperty(o, k, d)Fine control: writable, enumerable, getters/setters.
const { a, b = 10 } = objPull fields, with a default if missing.const { a: x } = objRename while unpacking → new varx.const [first, ...rest] = arr★Head + gather the tail into an array.const { a, ...others } = objRest collects the remaining own keys.[a, b] = [b, a]Swap two variables, no temp needed.const {a:{b}} = objNested destructuring reaches deep values.function f({ a, b }) {}★Destructure parameters right in the signature.const { a: x = 5 } = oRename and default in one shot.const [, , third] = arrSkip positions with empty holes.
function add(a, b) { return a+b }Declaration — hoisted, callable before its line.const add = (a, b) => a + b★Arrow — concise; implicit return, no ownthis.(x) => ({ x })Wrap an object literal in()or it reads as a block.greet(name = "friend")★Default parameters fill in forundefined.sum(...nums)Rest params gather all args into a real array.(function(){ ... })()IIFE — run once, keep names private.function outer(){ let n=0; return ()=>++n }Closure — inner fn keeps access to outer's vars.const f = function g(){}Named function expression — the name is visible only inside.arguments f.length f.nameargumentsis array-like & absent in arrows — prefer rest params.
obj.method()★Implicit:this= the object left of the dot.new Thing()new:this= the fresh instance.f.call(ctx, a) f.apply(ctx, [a])Explicit: you passthisin directly.const g = f.bind(ctx)Returns a copy permanently locked toctx.setTimeout(obj.m)Bare call losesthis→ default (undefined in strict).() => this.x★Arrows have no ownthis— they inherit lexically. Ideal for callbacks.globalThisThe one global object everywhere — window / global / self.
class Dog { constructor(n){ this.n=n } }★Runs onnew; sets up the instance.bark(){ ... }Methods live on the prototype, shared by all instances.get area(){} set area(v){}Accessors — used like a property, run like a method.static from(x){ ... }Called on the class itself, not instances.class Pup extends Dog { }Inherit; callsuper(...)first in the constructor.#secret = 0ES2022True private field — unreachable outside the class.static { ... }ES2022Static init block — one-time class setup.super(...) super.m()★Call the parent constructor / a parent method.count = 0ES2022Public instance field — no constructor needed.#reset() {}ES2022Private method — callable only inside the class.static #count = 0ES2022Private static field shared by the class.
const id = Symbol("id")Unique primitive — a collision-free object key.Symbol.for("k")Shared symbol from the global registry.[Symbol.iterator]() {}Well-known symbols hook objects into language protocols.new Proxy(target, handler)Intercept get / set / has / deleteProperty on an object.Reflect.get(o, k) .has()Default operations as functions — the natural pair for Proxy.Reflect.ownKeys(o)All own keys, including symbols and non-enumerables.obj[Symbol.toPrimitive]Customize how an object coerces to number / string.
if (c) { } else if (d) { } else { }Standard branching.switch (v) { case 1: ...; break; }Multi-way;breakor cases fall through.for (const x of arr)★Iterate values of any iterable. Your default loop.for (const k in obj)Iterates keys (incl. inherited) — for objects, not arrays.while (c) { } do { } while (c)Condition-first vs run-at-least-once.break continueExit the loop / skip to the next iteration.for (let i = 0; i < n; i++)★Classic C-style counter loop.outer: for (…) { break outer }Labeled loops — break/continue an outer loop.
function* ids(){ yield 1; yield 2 }★Generator —yieldpauses & resumes; produces values on demand.const g = ids(); g.next(){ value, done }each call, until done.[...ids()] for (const x of ids())Spread / loop consume any iterable.[Symbol.iterator]() { ... }Make your own object iterable by adding this method.async function* stream()Async generator —for await (const x of ...).yield* other()Delegate to another generator or iterable.const x = yield vTwo-way:next(val)injectsvalas the yield result.
p.then(v=>...).catch(e=>...)★Handle success / failure;.finally()runs either way.Promise.resolve(v) .reject(e)Make an already-settled promise.Promise.all([p1, p2])★Wait for all; rejects fast if any one fails.Promise.allSettled([...])ES2020Wait for all; never rejects — array of outcomes.Promise.any([...])ES2021First to fulfil wins; ignores rejections.Promise.race([...])First to settle (win or lose) wins.Promise.withResolvers()ES2024Get{ promise, resolve, reject }to settle from outside.new Promise((res, rej) => …)★Wrap a callback API into a promise.p.finally(() => …)ES2018Runs on settle — success or failure.
async function f(){ return 1 }★Always returns a Promise (wraps the value).const data = await fetch(url)★Pause until it settles; unwrap the value.try { await f() } catch (e) { }★Rejections throw — catch them like sync errors.const [a, b] = await Promise.all([...])Run in parallel; don'tawaitin a loop serially.await f() // top levelES2022Top-levelawait— in modules, no wrapper needed.arr.forEach(async ...)forEachignores the promises — usefor...of+await.for await (const x of s)ES2018Consume an async iterable, awaiting each value.await a; await b // serial★Sequential awaits are slow —Promise.allruns them in parallel.
const m = new Map()★Any-type keys, ordered, real.size. Beats{}for dynamic keys.m.set(k, v) m.get(k) m.has(k)Core map ops;setchains.const s = new Set([1,1,2])★Unique values;[...new Set(arr)]dedupes an array.s.add(x) s.has(x) s.delete(x)Set membership in O(1).new WeakMap() new WeakSet()Object keys held weakly — GC can reclaim them.Map.groupBy(arr, fn)ES2024LikeObject.groupBybut keys can be any type.m.size m.delete(k) m.clear()Count, remove one, empty all.for (const [k, v] of m)★Iterate entries in insertion order.[...new Set(arr)]★Dedupe an array in one line.new Map([[k, v]])Build from entry pairs; keys may be any type.
JSON.stringify(obj)★Object → JSON string.JSON.stringify(o, null, 2)Third arg = indent for pretty output.JSON.parse(str)★JSON string → object. Throws on bad input — wrap in try.JSON.parse(JSON.stringify(o))Old deep-clone hack — drops functions,Dates,undefined.structuredClone(obj)★ES2022Real deep clone — handles Dates, Maps, cycles.JSON.stringify(o, replacer)Filter/transform keys; atoJSON()method customizes output.JSON.parse(s, reviver)Transform values on the way in — e.g. revive Dates.
/ab+c/giLiteral + flags:globalignore-casemultilinesdotall.re.test(s)Boolean — does it match anywhere?s.match(re) s.matchAll(re)One match / iterator of all matches (needsg).s.replace(re, "$1")$1= capture group; a fn as arg = computed replace./(?<year>\d{4})/Named group →m.groups.year./[\p{Emoji}]/vES2024vflag — set operations & string properties in classes.flags: g i m s u y d★global · ignore-case · multiline · dotall · unicode · sticky · indices.s.replace(re, m => …)A function replacer computes each substitution.\d \w \s ^ $ \bDigit / word / space classes; start, end & word-boundary anchors.
try { } catch (e) { } finally { }★finallyalways runs — cleanup goes here.throw new Error("msg")★Throw an Error object, not a bare string.TypeError RangeError SyntaxErrorBuilt-in subclasses — checke instanceof TypeError.class AppError extends Error {}Custom errors — subclassError, setthis.name.new Error("x", { cause: err })ES2022Chain the original error for context.try {} catch {}ES2019Optional catch binding — omit(e)when unused.AggregateErrorES2021Thrown byPromise.anywhen all reject; holds.errors.throw e // re-throwRe-throw inside catch to let an outer handler deal with it.
export function f(){} export const x★Named exports — many per file.export default AppOne default per file — the "main" thing.import { f, x } from "./m.js"★Named imports — braces & matching names.import App from "./app.js"Default import — no braces, name is yours.import * as utils from "./u.js"Namespace — all named exports on one object.const m = await import("./m.js")ES2020Dynamic import — load on demand, returns a Promise.export { x as y }★Rename on export;import { a as b }renames on import.export * from "./m.js"Re-export another module's public API.
console.log("x", v)★Standard output; comma-separate any number of values.console.error() .warn()Stderr and warning channels.console.table(rows)Render arrays / objects as an aligned table.console.dir(o) { obj }★{ obj }shorthand labels a value in the log.console.assert(cond, msg)Logs only when the condition is false.console.time("t") .timeEnd()Measure elapsed time between the paired calls.console.group() .count()Indent nested logs; tally how often a line runs.debuggerPauses execution when devtools are open.