Working with Data — Cheat Sheet
JavaScript & TypeScript · 6 topics. Download the PDF or the Instagram carousel and share it.
Arrays — map, filter, reduce and the Rest
The array methods are how JavaScript expresses data transformation. Knowing which ones mutate and which return a new array is more important than knowing all of them.
- ✓map transforms, filter selects, reduce collapses — most other methods are conveniences on these
- ✓sort, reverse, splice, push and pop mutate in place; map, filter, slice and concat return new arrays
- ✓sort() with no comparator sorts as strings, so [100, 25, 9] does not sort numerically
- ✓Copy before sorting ([...arr].sort()) or use toSorted() — mutating shared arrays breaks React renders
- ✓find returns the item, findIndex the position, some/every return booleans
const orders = [
{ id: 1, total: 4500, status: 'paid' },
{ id: 2, total: 1200, status: 'pending' },
{ id: 3, total: 8900, status: 'paid' },
]
// map — same length, transformed items
orders.map(o => o.total) // [4500, 1200, 8900]
// filter — fewer items, unchanged
orders.filter(o => o.status === 'paid') // 2 orders
// reduce — one value out
orders.reduce((sum, o) => sum + o.total, 0) // 14600
// Chaining is the normal shape:
const paidTotal = orders
.filter(o => o.status === 'paid')
.reduce((sum, o) => sum + o.total, 0) // 13400Objects — Keys, Spread and Immutable Updates
Objects are the workhorse structure. Reading, iterating and — most importantly — updating them without mutation is the skill that carries straight into React state.
- ✓Object.entries() with destructuring is the idiomatic way to iterate key-value pairs
- ✓Spread copies one level deep — nested updates require spreading at every level you change
- ✓Removing a key is done with rest destructuring: const { drop, ...rest } = obj
- ✓Object.hasOwn() checks own properties; the `in` operator also finds inherited ones
- ✓Two objects with identical contents are not ===; this reference comparison is why React re-renders on new objects
const user = { name: 'Asha', role: 'student' }
user.name // known key
user['role'] // same thing
const key = 'role'
user[key] // computed key
Object.keys(user) // ['name', 'role']
Object.values(user) // ['Asha', 'student']
Object.entries(user) // [['name','Asha'], ['role','student']]
for (const [k, v] of Object.entries(user)) { ... }
// Building an object from pairs, and back:
Object.fromEntries([['a', 1], ['b', 2]]) // { a: 1, b: 2 }
// Computed keys in a literal:
const field = 'email'
const patch = { [field]: 'a@b.com', [`${field}Verified`]: false }Destructuring & Spread — Pulling Data Apart
Destructuring extracts values from objects and arrays into variables; spread and rest do the reverse. Together they remove most of the boilerplate around passing data around.
- ✓Objects destructure by name and arrays by position; both support defaults and renaming
- ✓A destructured parameter object turns positional arguments into named ones the caller cannot mis-order
- ✓Adding `= {}` to a destructured parameter lets the caller omit the argument entirely
- ✓Rest collects on the left of an assignment; spread expands on the right — same syntax, opposite direction
- ✓The { consumed, ...rest } pattern is how React components pass unknown props through to a DOM element
// Objects — by name
const { name, role = 'student' } = user
const { name: userName } = user // rename
const { address: { city } } = user // nested
// Arrays — by position
const [first, second] = items
const [, , third] = items // skip with commas
const [head, ...tail] = items // rest
// Swapping without a temp variable
let a = 1, b = 2
;[a, b] = [b, a]
// In a for-of over entries
for (const [key, value] of Object.entries(obj)) { ... }Strings — Templates, Methods and Unicode
Template literals handle interpolation and multi-line text; the method set covers most parsing needs. The one trap is that .length counts UTF-16 code units, not characters.
- ✓Strings are immutable — every method returns a new string
- ✓Template literals handle interpolation, multi-line text and expressions; tagged templates power escaping libraries
- ✓replaceAll() replaces every occurrence without needing a global regex
- ✓.length counts UTF-16 code units, so emoji count as 2 — spread or Intl.Segmenter for real character counts
- ✓Intl.NumberFormat with en-IN gives correct rupee formatting including the Indian digit grouping
const name = 'Asha'
const total = 4500
`Hello ${name}, your total is ₹${(total / 100).toFixed(2)}`
// Multi-line, preserved exactly
const query = `
SELECT id, title
FROM problems
WHERE difficulty = '${level}'
`
// Any expression, including calls and ternaries
`You have ${count} item${count === 1 ? '' : 's'}`
// Tagged templates — the function receives parts and values
function html(strings, ...values) { ... }
html`<p>${userInput}</p>` // used for escaping, styled-components, SQL buildersMap & Set — When a Plain Object Is Not Enough
Map allows any value as a key and preserves insertion order; Set stores unique values. Both are the right answer more often than the object-as-dictionary habit suggests.
- ✓Map accepts any value as a key; object keys are always coerced to strings
- ✓Map preserves insertion order, exposes .size, and iterates without prototype pollution
- ✓Set gives O(1) membership — replacing .includes() inside a loop turns O(n*m) into O(n)
- ✓[...new Set(arr)] is the idiomatic deduplication
- ✓WeakMap holds keys weakly so entries do not prevent garbage collection — use it to attach data to DOM nodes
const cache = new Map()
cache.set('key', value)
cache.set(userObject, metadata) // an object as a key — impossible with {}
cache.get('key')
cache.has('key') // no prototype confusion
cache.delete('key')
cache.size // a property, not Object.keys().length
for (const [k, v] of cache) { ... } // insertion order, guaranteed
// The object trap Map avoids:
const obj = {}
obj[1] = 'a'; obj['1'] = 'b'
Object.keys(obj) // ['1'] — the number became a string
const map = new Map()
map.set(1, 'a').set('1', 'b')
map.size // 2 — distinct keysJSON — Serialising, Parsing and the Sharp Edges
JSON.stringify and JSON.parse move data between JavaScript and the wire. What they silently drop — undefined, functions, Dates, Map, Set — is the part worth knowing.
- ✓JSON supports string, number, boolean, null, array and object — everything else is converted or dropped
- ✓undefined and functions are removed from objects entirely, but become null inside arrays
- ✓Dates become ISO strings and do not come back as Dates — use a reviver if you need them typed
- ✓JSON.parse throws on malformed input; check response.ok before parsing a fetch body
- ✓structuredClone() is a better deep clone than JSON round-tripping, which loses Dates, Map and Set
JSON.stringify({
str: 'ok', // survives
num: 42, // survives
bool: true, // survives
nil: null, // survives
arr: [1, 2], // survives
obj: { a: 1 }, // survives
undef: undefined, // KEY REMOVED entirely
fn: () => {}, // KEY REMOVED
date: new Date(), // becomes an ISO string, stays a string
map: new Map([[1,2]]), // becomes {} — contents lost
set: new Set([1]), // becomes {} — contents lost
nan: NaN, // becomes null
inf: Infinity, // becomes null
})
// BigInt throws: "Do not know how to serialize a BigInt"
// In an array, undefined becomes null rather than disappearing:
JSON.stringify([1, undefined, 3]) // '[1,null,3]'