Toolmingo
Guides15 min read

JavaScript Cheat Sheet: Syntax, Methods, and Patterns

A complete JavaScript cheat sheet — variables, data types, functions, arrays, objects, classes, async/await, modules, and common patterns. Copy-ready examples.

JavaScript powers every modern web app. This reference covers the entire language — variables through async patterns — with copy-ready code you can use right now.

Quick reference

The 25 patterns that cover 90% of everyday JavaScript.

Pattern What it does
let x = 5 Mutable variable
const PI = 3.14 Immutable binding
typeof x Get type as string
x ?? 'default' Nullish coalescing
x?.y?.z Optional chaining
[...arr] Spread / shallow copy
{ ...obj } Object spread
const { a, b } = obj Object destructuring
const [x, y] = arr Array destructuring
`Hello ${name}` Template literal
arr.map(fn) Transform each element
arr.filter(fn) Keep matching elements
arr.reduce(fn, init) Fold to single value
arr.find(fn) First matching element
Object.keys(obj) Array of keys
Object.entries(obj) Array of [key, value] pairs
Promise.all([...]) Await all promises
async function f(){} Async function
await fetch(url) Await HTTP response
class Foo { } Class declaration
import { x } from './m' Named import
export default fn Default export
try { } catch (e) { } Error handling
setTimeout(fn, ms) Run later
JSON.parse(str) Parse JSON string

Variables and data types

Declaration keywords

var name = 'old';     // function-scoped, hoisted — avoid
let count = 0;        // block-scoped, reassignable
const PI = 3.14159;   // block-scoped, not reassignable (binding)

Rule of thumb: always const; use let when you need to reassign; never var.

Primitive types

// Seven primitives
let n = 42;              // number
let big = 9007199254740993n; // bigint
let str = 'hello';       // string
let bool = true;         // boolean
let nothing = null;      // null (intentional absence)
let missing;             // undefined (uninitialized)
let id = Symbol('uid');  // symbol (unique key)

// Check type
typeof 42          // 'number'
typeof 'hi'        // 'string'
typeof null        // 'object' — historical quirk
typeof undefined   // 'undefined'
typeof Symbol()    // 'symbol'
Array.isArray([])  // true

Type coercion and comparison

// Always use === (strict equality)
0 == false   // true  — avoid
0 === false  // false — correct

null == undefined   // true
null === undefined  // false

// Truthy / falsy values
// Falsy: false, 0, -0, 0n, '', null, undefined, NaN
// Truthy: everything else, including [], {}, '0', 'false'

Boolean(0)    // false
Boolean([])   // true
Boolean('')   // false
Boolean(' ')  // true

Strings

const s = 'Hello, World!';

// Length and access
s.length          // 13
s[0]              // 'H'
s.at(-1)          // '!' — last character (ES2022)

// Search
s.includes('World')      // true
s.startsWith('Hello')    // true
s.endsWith('!')          // true
s.indexOf('o')           // 4
s.lastIndexOf('o')       // 8

// Extract
s.slice(7, 12)           // 'World'
s.slice(-6)              // 'World!'
s.substring(7, 12)       // 'World'

// Transform
s.toLowerCase()          // 'hello, world!'
s.toUpperCase()          // 'HELLO, WORLD!'
s.trim()                 // removes leading/trailing whitespace
s.trimStart()
s.trimEnd()
s.replace('World', 'JS') // 'Hello, JS!'
s.replaceAll('l', 'L')   // 'HeLLo, WorLd!'
s.split(', ')            // ['Hello', 'World!']
s.repeat(2)              // 'Hello, World!Hello, World!'
s.padStart(15, '-')      // '--Hello, World!'
s.padEnd(15, '-')        // 'Hello, World!--'

// Template literals
const name = 'Alice';
const age = 30;
`${name} is ${age} years old`    // 'Alice is 30 years old'
`Line 1
Line 2`                           // multi-line string

// Tagged templates
function highlight(strings, ...vals) {
  return strings.reduce((acc, str, i) =>
    acc + str + (vals[i] !== undefined ? `<b>${vals[i]}</b>` : ''), '');
}
highlight`Hello ${name}, you are ${age}!`
// 'Hello <b>Alice</b>, you are <b>30</b>!'

Numbers

// Arithmetic
5 + 3    // 8
10 - 4   // 6
3 * 7    // 21
15 / 4   // 3.75
15 % 4   // 3  (remainder)
2 ** 10  // 1024 (exponentiation)

// Math utilities
Math.round(4.6)    // 5
Math.floor(4.9)    // 4
Math.ceil(4.1)     // 5
Math.abs(-7)       // 7
Math.max(1, 5, 3)  // 5
Math.min(1, 5, 3)  // 1
Math.sqrt(16)      // 4
Math.pow(2, 8)     // 256
Math.random()      // 0 ≤ n < 1

// Parsing
parseInt('42px')      // 42
parseInt('0xFF', 16)  // 255
parseFloat('3.14em')  // 3.14
Number('42')          // 42
Number('')            // 0
Number('abc')         // NaN

// Special values
Infinity
-Infinity
NaN            // Not a Number
isNaN(NaN)     // true
isFinite(1/0)  // false
Number.isInteger(4.0)  // true

// Formatting
(1234567.89).toFixed(2)         // '1234567.89'
(1234567.89).toLocaleString()   // '1,234,567.89' (locale-dependent)

Control flow

Conditionals

// if / else if / else
if (score >= 90) {
  grade = 'A';
} else if (score >= 80) {
  grade = 'B';
} else {
  grade = 'F';
}

// Ternary
const label = isAdmin ? 'Admin' : 'User';

// Nullish coalescing
const port = process.env.PORT ?? 3000;

// Logical OR fallback (careful: 0 and '' are falsy)
const name = userInput || 'Anonymous';

// Optional chaining
const city = user?.address?.city;          // undefined if any is null/undefined
const fn = obj.method?.();                 // call only if method exists

// switch
switch (day) {
  case 'Mon':
  case 'Tue':
    console.log('Weekday');
    break;
  case 'Sat':
  case 'Sun':
    console.log('Weekend');
    break;
  default:
    console.log('Unknown');
}

Loops

// for
for (let i = 0; i < 5; i++) { }

// for...of (iterables: arrays, strings, Maps, Sets)
for (const item of items) { }

// for...in (object keys — prefer Object.keys())
for (const key in obj) {
  if (Object.hasOwn(obj, key)) { }  // skip prototype keys
}

// while
while (condition) { }

// do...while (runs at least once)
do { } while (condition);

// Loop control
break;     // exit loop
continue;  // skip to next iteration

// Array iteration methods (preferred over loops)
arr.forEach((item, index) => { });
arr.map(item => item * 2);
arr.filter(item => item > 0);
arr.reduce((acc, item) => acc + item, 0);
arr.every(item => item > 0);   // all match?
arr.some(item => item > 0);    // any match?

Functions

// Function declaration (hoisted)
function greet(name) {
  return `Hello, ${name}!`;
}

// Function expression
const greet = function(name) {
  return `Hello, ${name}!`;
};

// Arrow function
const greet = (name) => `Hello, ${name}!`;

// Arrow function with body
const add = (a, b) => {
  const sum = a + b;
  return sum;
};

// Default parameters
function createUser(name, role = 'user', active = true) {
  return { name, role, active };
}

// Rest parameters
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4);  // 10

// Destructured parameters
function display({ name, age = 0 }) {
  console.log(`${name} (${age})`);
}

// Immediately Invoked Function Expression (IIFE)
(function() {
  // private scope
})();

Closures

function makeCounter(start = 0) {
  let count = start;
  return {
    increment() { count++; },
    decrement() { count--; },
    value() { return count; },
  };
}
const counter = makeCounter(10);
counter.increment();
counter.value();  // 11

Higher-order functions

// Function that returns a function
const multiply = (factor) => (n) => n * factor;
const double = multiply(2);
double(5);  // 10

// Function that accepts a function
function pipe(...fns) {
  return (x) => fns.reduce((v, f) => f(v), x);
}
const transform = pipe(
  (s) => s.trim(),
  (s) => s.toLowerCase(),
  (s) => s.replace(/ /g, '-'),
);
transform('  Hello World  ');  // 'hello-world'

Arrays

// Create
const arr = [1, 2, 3];
const filled = new Array(5).fill(0);       // [0,0,0,0,0]
const range = Array.from({ length: 5 }, (_, i) => i + 1);  // [1,2,3,4,5]
const fromStr = Array.from('hello');       // ['h','e','l','l','o']

// Read
arr[0]           // 1
arr.at(-1)       // 3 — last element
arr.length       // 3

// Mutating methods (change the original array)
arr.push(4)           // add to end, returns new length
arr.pop()             // remove from end, returns element
arr.unshift(0)        // add to start, returns new length
arr.shift()           // remove from start, returns element
arr.splice(1, 2)      // remove 2 elements at index 1
arr.splice(1, 0, 'a') // insert 'a' at index 1
arr.sort()            // sort in-place (alphabetical by default)
arr.sort((a, b) => a - b)  // sort numerically ascending
arr.reverse()         // reverse in-place
arr.fill(0, 1, 3)     // fill indices 1-2 with 0

// Non-mutating methods (return new array/value)
arr.slice(1, 3)              // ['b','c'] — copy subarray
arr.concat([4, 5])           // merge arrays
arr.join(' - ')              // 'a - b - c'
arr.indexOf(2)               // first index of 2 (or -1)
arr.lastIndexOf(2)           // last index
arr.includes(2)              // true/false
arr.find(x => x > 2)        // first match
arr.findIndex(x => x > 2)   // index of first match
arr.findLast(x => x > 2)    // last match (ES2023)
arr.map(x => x * 2)         // transform each
arr.filter(x => x % 2 === 0) // keep evens
arr.reduce((acc, x) => acc + x, 0)  // sum
arr.flat()                   // flatten one level
arr.flat(Infinity)           // flatten all levels
arr.flatMap(x => [x, x * 2]) // map then flatten one level
arr.every(x => x > 0)       // all positive?
arr.some(x => x > 0)        // any positive?

// ES2023 non-mutating alternatives
arr.toSorted((a, b) => a - b)   // sorted copy
arr.toReversed()                 // reversed copy
arr.toSpliced(1, 1, 'x')        // spliced copy
arr.with(0, 99)                  // copy with index replaced

// Spread and destructuring
const copy = [...arr];
const merged = [...arr1, ...arr2];
const [first, second, ...rest] = arr;

Objects

// Object literal
const user = {
  name: 'Alice',
  age: 30,
  greet() {            // shorthand method
    return `Hi, ${this.name}`;
  },
};

// Access and modify
user.name             // 'Alice'
user['age']           // 30 — bracket notation for dynamic keys
user.email = 'a@b.c'  // add property
delete user.age       // remove property

// Computed keys
const key = 'status';
const obj = { [key]: 'active' };  // { status: 'active' }

// Shorthand property names
const name = 'Alice';
const age = 30;
const person = { name, age };     // { name: 'Alice', age: 30 }

// Spread and merge
const defaults = { theme: 'dark', lang: 'en' };
const settings = { ...defaults, lang: 'fr' };  // { theme: 'dark', lang: 'fr' }

// Destructuring
const { name, age, email = 'none' } = user;    // with default
const { name: userName } = user;               // rename

// Nested destructuring
const { address: { city } } = user;

// Object methods
Object.keys(obj)         // array of keys
Object.values(obj)       // array of values
Object.entries(obj)      // array of [key, value] pairs
Object.assign({}, a, b)  // shallow merge (mutates first arg)
Object.freeze(obj)       // make immutable (shallow)
Object.fromEntries(entries)  // convert entries back to object
Object.hasOwn(obj, key)      // safer than hasOwnProperty

// Convert entries
const map = new Map([['a', 1], ['b', 2]]);
Object.fromEntries(map)  // { a: 1, b: 2 }

const filtered = Object.fromEntries(
  Object.entries(obj).filter(([, v]) => v !== null)
);

Classes

class Animal {
  #name;  // private field (ES2022)

  constructor(name, sound) {
    this.#name = name;
    this.sound = sound;
  }

  // Getter
  get name() { return this.#name; }

  // Instance method
  speak() {
    return `${this.#name} says ${this.sound}`;
  }

  // Static method
  static create(name, sound) {
    return new Animal(name, sound);
  }
}

class Dog extends Animal {
  #tricks = [];

  constructor(name) {
    super(name, 'woof');
  }

  learn(trick) {
    this.#tricks.push(trick);
    return this;  // for chaining
  }

  perform() {
    return this.#tricks.join(', ');
  }
}

const dog = new Dog('Rex');
dog.learn('sit').learn('shake');  // method chaining
dog.speak();    // 'Rex says woof'
dog instanceof Animal  // true

Destructuring and spread (advanced)

// Function parameter defaults with destructuring
function connect({
  host = 'localhost',
  port = 5432,
  ssl = false,
} = {}) {  // default empty object so calling with no args works
  return `${ssl ? 'ssl://' : ''}${host}:${port}`;
}

// Swap variables
let a = 1, b = 2;
[a, b] = [b, a];

// Skip elements
const [,, third] = [1, 2, 3];  // 3

// Nested array destructuring
const [[x1, y1], [x2, y2]] = [[0, 0], [10, 10]];

// Mix spread with destructuring
function merge(target, ...sources) {
  return Object.assign(target, ...sources);
}

Async JavaScript

Promises

// Create a promise
const delay = (ms) =>
  new Promise((resolve) => setTimeout(resolve, ms));

// Chain
fetch('/api/users')
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((err) => console.error(err))
  .finally(() => console.log('done'));

// Promise combinators
Promise.all([p1, p2, p3])        // resolves when all resolve; rejects on first rejection
Promise.allSettled([p1, p2, p3]) // resolves when all settle (success or fail)
Promise.race([p1, p2])           // resolves/rejects with the first to settle
Promise.any([p1, p2, p3])        // resolves with first success; rejects if all fail

async / await

async function fetchUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error('Fetch failed:', err);
    throw err;
  }
}

// Parallel execution
async function loadAll() {
  const [users, posts] = await Promise.all([
    fetchUser(1),
    fetchPosts(),
  ]);
  return { users, posts };
}

// Sequential (each awaits the previous)
async function processSequential(ids) {
  const results = [];
  for (const id of ids) {
    results.push(await fetchUser(id));  // sequential
  }
  return results;
}

// Parallel with concurrency limit
async function batchFetch(ids, concurrency = 3) {
  const results = [];
  for (let i = 0; i < ids.length; i += concurrency) {
    const batch = ids.slice(i, i + concurrency);
    results.push(...await Promise.all(batch.map(fetchUser)));
  }
  return results;
}

Error handling

// try / catch / finally
try {
  const data = JSON.parse(rawInput);
  process(data);
} catch (err) {
  if (err instanceof SyntaxError) {
    console.error('Invalid JSON:', err.message);
  } else {
    throw err;  // re-throw unexpected errors
  }
} finally {
  cleanup();  // always runs
}

// Custom error classes
class AppError extends Error {
  constructor(message, code) {
    super(message);
    this.name = 'AppError';
    this.code = code;
  }
}

class NotFoundError extends AppError {
  constructor(resource) {
    super(`${resource} not found`, 404);
    this.name = 'NotFoundError';
  }
}

// Usage
try {
  throw new NotFoundError('User');
} catch (err) {
  if (err instanceof NotFoundError) {
    console.log(err.code);  // 404
  }
}

Modules (ES Modules)

// math.js — named exports
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }

// Default export
export default class Calculator { }

// Re-export
export { add, subtract } from './math.js';
export * from './utils.js';

// ---

// Import named
import { add, subtract } from './math.js';

// Import default
import Calculator from './math.js';

// Import both
import Calculator, { PI, add } from './math.js';

// Import all as namespace
import * as math from './math.js';
math.add(1, 2);

// Dynamic import (lazy loading)
const { default: heavy } = await import('./heavy-module.js');

// import.meta (ESM only)
import.meta.url      // current module URL
import.meta.env      // Vite/build tool env vars

Collections: Map and Set

// Map — ordered key-value with any key type
const map = new Map();
map.set('key', 'value');
map.set(42, 'number key');
map.set({ id: 1 }, 'object key');
map.get('key');       // 'value'
map.has('key');       // true
map.size;             // 3
map.delete('key');
map.clear();

// Iterate
for (const [key, value] of map) { }
map.forEach((value, key) => { });
[...map.keys()]       // array of keys
[...map.values()]     // array of values
[...map.entries()]    // array of [key, value]

// Object → Map → Object
const obj = { a: 1, b: 2 };
const m = new Map(Object.entries(obj));
const back = Object.fromEntries(m);

// Set — unique values
const set = new Set([1, 2, 3, 2, 1]);  // {1, 2, 3}
set.add(4);
set.has(2);    // true
set.size;      // 4
set.delete(2);
[...set]       // [1, 3, 4]

// Deduplicate an array
const unique = [...new Set(arr)];

// Set operations
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const union        = new Set([...a, ...b]);               // {1,2,3,4}
const intersection = new Set([...a].filter(x => b.has(x))); // {2,3}
const difference   = new Set([...a].filter(x => !b.has(x))); // {1}

Common patterns

Safe JSON parse

function safeParseJSON(str, fallback = null) {
  try {
    return JSON.parse(str);
  } catch {
    return fallback;
  }
}

Deep clone

// Simple (no functions, dates, or circular refs)
const clone = JSON.parse(JSON.stringify(obj));

// Modern (handles Dates, RegExp, typed arrays, Maps, Sets)
const clone = structuredClone(obj);

Debounce

function debounce(fn, wait) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), wait);
  };
}
const search = debounce((q) => fetchResults(q), 300);

Throttle

function throttle(fn, limit) {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      return fn(...args);
    }
  };
}

Memoize

function memoize(fn) {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

Group array by key

// ES2024 Object.groupBy
const grouped = Object.groupBy(people, ({ age }) =>
  age >= 18 ? 'adults' : 'minors'
);

// Fallback (older environments)
const grouped = people.reduce((acc, person) => {
  const key = person.age >= 18 ? 'adults' : 'minors';
  (acc[key] ??= []).push(person);
  return acc;
}, {});

Flatten nested array

const nested = [1, [2, [3, [4]]]];
nested.flat()          // [1, 2, [3, [4]]]
nested.flat(Infinity)  // [1, 2, 3, 4]

Common mistakes

Mistake Why it fails Fix
arr.forEach with async forEach ignores returned promises Use for...of or Promise.all(arr.map(...))
0 == false Loose equality coerces types Always use ===
Mutating state in map/filter Side effects break predictability Keep callbacks pure; use reduce for accumulation
const obj = {}; obj.key = v const prevents reassignment, not mutation Use Object.freeze if immutability is needed
typeof null === 'object' Historical JS bug Use x === null to check for null
var in loops Shared binding across iterations Use let
Not handling rejected promises Unhandled rejections crash Node.js Always .catch() or try/catch
arr.sort() sorts lexicographically [10,2,1].sort()[1,10,2] Pass comparator: arr.sort((a,b) => a-b)

JavaScript vs TypeScript quick reference

Feature JavaScript TypeScript
Type annotations No let x: number
Interfaces No interface Foo { x: number }
Generics No function id<T>(x: T): T
Enums No enum Color { Red, Green }
Compile step No tsc or bundler
Runtime errors from types Yes Caught at compile time
any type N/A Opt-in escape hatch

FAQ

What is the difference between == and ===? === checks value and type (no coercion). == coerces types before comparing. Use === always unless you explicitly want type coercion (rare).

What is the difference between null and undefined? undefined means a variable was declared but not assigned, or a property doesn't exist. null is an intentional "no value." Both are falsy; use ?? (nullish coalescing) to handle both: x ?? 'default'.

How do I copy an object without mutating the original? Shallow: { ...obj } or Object.assign({}, obj). Deep (handles nested): structuredClone(obj) (modern environments) or JSON.parse(JSON.stringify(obj)) (no Date/Function/circular).

When should I use Map instead of a plain object? Use Map when: keys aren't strings (e.g., object keys), you need insertion-order iteration guaranteed, you frequently add/delete keys, or you need .size. Use objects for simple static data and when interacting with JSON.

What is the event loop? JavaScript is single-threaded. The event loop processes the call stack first, then microtasks (Promises, queueMicrotask), then macrotasks (setTimeout, setInterval, I/O). await yields to the event loop, allowing other microtasks to run.

What is hoisting? Variable declarations with var and function declarations are moved to the top of their scope before execution. let and const are hoisted but not initialized — accessing them before declaration throws a ReferenceError (the "temporal dead zone").

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools