JavaScript Cheatsheet

Destructuring and Spread

Use this JavaScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Array Destructuring

const [a, b, c] = [1, 2, 3];
// a = 1, b = 2, c = 3

// Skip elements
const [, second, , fourth] = [1, 2, 3, 4];
// second = 2, fourth = 4

// Default values
const [x = 0, y = 0, z = 0] = [1, 2];
// x = 1, y = 2, z = 0  (default used)

// Rest element — must be last
const [first, ...rest] = [1, 2, 3, 4];
// first = 1, rest = [2, 3, 4]

// Swap variables
let p = 1, q = 2;
[p, q] = [q, p];
// p = 2, q = 1

// Nested
const [[a1, a2], [b1, b2]] = [[1, 2], [3, 4]];

// From function return
function minMax(arr) { return [Math.min(...arr), Math.max(...arr)]; }
const [min, max] = minMax([3, 1, 4, 1, 5]);

// Iterables (works with any iterable, not just arrays)
const [first2, second2] = new Set([10, 20, 30]);
const [k, v] = new Map([["a", 1]]).entries().next().value;
const [char1, char2] = "hello"; // char1 = "h", char2 = "e"

Object Destructuring

const user = { name: "Alice", age: 30, role: "admin" };

// Basic
const { name, age } = user;

// Rename (alias)
const { name: userName, age: userAge } = user;
// userName = "Alice", userAge = 30

// Default values
const { name: n, score = 100 } = user;
// score = 100 (property missing)

// Default + rename
const { role: userRole = "guest" } = user;

// Rest
const { name: nm, ...rest } = user;
// nm = "Alice", rest = { age: 30, role: "admin" }

// Nested object destructuring
const { address: { city, zip = "00000" } } = { address: { city: "NYC" } };

// Deeply nested
const { a: { b: { c: deepValue } } } = { a: { b: { c: 42 } } };

// Combined with computed keys
const key = "name";
const { [key]: val } = user; // val = "Alice"

Destructuring in Function Parameters

// Object params
function greet({ name, greeting = "Hello" }) {
  return `${greeting}, ${name}!`;
}
greet({ name: "Alice" });             // "Hello, Alice!"
greet({ name: "Bob", greeting: "Hi" }); // "Hi, Bob!"

// With default for entire param (so calling with no arg works)
function setup({ host = "localhost", port = 3000 } = {}) {
  return `${host}:${port}`;
}
setup();               // "localhost:3000"
setup({ port: 4000 }); // "localhost:4000"

// Array params
function first([a, b]) { return a; }

// Mixed
function process([first3, ...items], { verbose = false } = {}) { /* ... */ }

Spread Operator (...)

Spread in Arrays

const a = [1, 2, 3];
const b = [4, 5, 6];

[...a, ...b]          // [1,2,3,4,5,6]  concat
[0, ...a, ...b, 7]    // [0,1,2,3,4,5,6,7]
const copy = [...a]   // shallow copy

Math.max(...a)        // 3  (spread as function args)
console.log(...a)     // 1 2 3

// Spread string into chars
[..."hello"]          // ["h","e","l","l","o"]

// Spread any iterable
[...new Set([1,2,3,2,1])] // [1,2,3]
[...new Map([["a",1]])]   // [["a",1]]
[...document.querySelectorAll("div")]

Spread in Objects (ES2018)

const obj = { a: 1, b: 2 };
const ext = { c: 3, d: 4 };

{ ...obj, ...ext }        // { a:1, b:2, c:3, d:4 }  merge
const copy2 = { ...obj }  // shallow copy

// Later keys override earlier
{ ...obj, b: 99 }         // { a:1, b:99 }  override
{ b: 99, ...obj }         // { b:2, a:1 }   obj wins

// Conditional spread
const extra = condition ? { extra: true } : {};
const result = { ...obj, ...extra };

// Concise conditional (ES2018+)
const result2 = { ...obj, ...(condition && { extra: true }) };
// Note: if condition is false, spreading false does nothing

Spread in Function Calls

function add(a, b, c) { return a + b + c; }
const nums = [1, 2, 3];
add(...nums)           // 6

// Before/after other args
add(0, ...nums.slice(0,2)) // 0+1+2 = 3
Math.min(...nums, 0)       // 0

Rest Parameters

// Collect remaining arguments into an array
function sum(first4, ...rest) {
  return rest.reduce((a, b) => a + b, first4);
}
sum(1, 2, 3, 4) // 10

// Rest must be the last parameter
function log(level, ...messages) {
  console.log(`[${level}]`, messages.join(" "));
}

// Rest vs arguments object
function legacy() {
  const args = Array.from(arguments); // old way, not in arrows
}
function modern(...args) {
  // args is a real Array
}

Nested Destructuring

const data = {
  user: {
    name: "Alice",
    address: {
      city: "NYC",
      zip: "10001",
    },
    scores: [90, 85, 92],
  },
};

const {
  user: {
    name: uName,
    address: { city, zip },
    scores: [topScore, ...otherScores],
  },
} = data;
// uName = "Alice", city = "NYC", zip = "10001"
// topScore = 90, otherScores = [85, 92]

// API response pattern
const {
  data: { users: [firstUser, ...remainingUsers] = [] } = {},
  error,
  status = 200,
} = response;

Assignment Destructuring (without declaration)

let a3, b3;

// Object — must wrap in parens (block scope ambiguity)
({ a: a3, b: b3 } = { a: 1, b: 2 });

// Array — no parens needed
[a3, b3] = [1, 2];

// Partial reassignment
let x2 = 1, y2 = 2, z2 = 3;
({ x: x2, y: y2 } = { x: 10, y: 20 });
// x2 = 10, y2 = 20, z2 still = 3

Common Patterns

// Clone with override
const updated = { ...user, age: 31 };

// Remove a property (omit pattern)
const { password, ...safeUser } = user;

// Rename imported key
const { very_long_key: shortName } = apiResponse;

// Destructure in for...of
const people = [{ name: "A", age: 1 }, { name: "B", age: 2 }];
for (const { name, age } of people) {
  console.log(name, age);
}

// Destructure Map entries
for (const [key, value] of map.entries()) {
  console.log(key, value);
}

// Array of arrays
const matrix = [[1,2],[3,4],[5,6]];
for (const [x3, y3] of matrix) {
  console.log(x3, y3);
}

// Function returning multiple values
function stats(arr) {
  return {
    min: Math.min(...arr),
    max: Math.max(...arr),
    sum: arr.reduce((a, b) => a + b, 0),
  };
}
const { min, max, sum } = stats([1, 2, 3, 4, 5]);

// Selective import-style picking
const { map: mapFn, filter: filterFn } = Array.prototype;