JavaScript Cheat Sheet You'll Use Every Day (Array Methods, Async and Traps)
β‘ Quick Answer
A practical JavaScript cheat sheet β array methods, destructuring, async/await, optional chaining, and the equality and this-binding traps that catch everyone.
Get more content like this on Telegram!
Daily AI tips, notes & resources β free
Advertisement
JavaScript Cheat Sheet You'll Use Every Day
JavaScript's array methods alone justify a reference card. There are a dozen of them, their names are just similar enough to blur together under pressure, and picking the right one is most of what makes JavaScript read cleanly.
This sheet covers the daily working set, the modern syntax that replaced older patterns, and the four traps that produce bugs which survive code review.
Updated for 2026. ES2020 and later; all features are supported in every current browser and Node.js.
Variables
const name = "Ada"; // cannot be reassigned β the default
let count = 0; // can be reassigned
var old = 1; // function-scoped, hoisted β do not useUse const by default. Reach for let only when you genuinely reassign. var has no remaining use case in new code.
A clarification that trips people up: const prevents reassignment, not mutation.
const items = [1, 2];
items.push(3); // fine β mutating the array
items = [4]; // TypeError β reassigning the bindingArray Methods
The single most important table on this page.
| Method | Returns | Use for |
|---|---|---|
map | New array, same length | Transforming every item |
filter | New array, fewer items | Keeping items that match |
find | First match, or undefined | Locating one item |
findIndex | Index, or -1 | Locating a position |
some | Boolean | "Does any item match?" |
every | Boolean | "Do all items match?" |
reduce | Anything | Collapsing to a single value |
flatMap | Flattened new array | Map that produces arrays |
forEach | undefined | Side effects only |
includes | Boolean | "Is this value present?" |
sort | The same array, mutated | Ordering |
const nums = [1, 2, 3, 4];
nums.map(n => n * 2); // [2, 4, 6, 8]
nums.filter(n => n % 2 === 0); // [2, 4]
nums.find(n => n > 2); // 3
nums.some(n => n > 3); // true
nums.every(n => n > 0); // true
nums.reduce((sum, n) => sum + n, 0); // 10
nums.includes(3); // truemap versus forEach: map builds and returns a new array. If you are not using that array, you allocated it for nothing and signalled the wrong intent. Use forEach for side effects.
sort mutates and sorts as strings by default:
[10, 9, 1].sort(); // [1, 10, 9] β string comparison
[10, 9, 1].sort((a, b) => a - b); // [1, 9, 10] β correct
[...items].sort((a, b) => a - b); // copy first if you need the originalThat default is a genuine design mistake in the language, and it produces wrong results quietly. Always pass a comparator for numbers.
Chaining is the point:
const names = users
.filter(u => u.active)
.map(u => u.name)
.sort();When to use a plain loop: you cannot break out of map, filter, or forEach. If you need early exit, use for...of.
for (const item of items) {
if (item.bad) break;
}Destructuring
const { name, age } = user;
const { name, age = 18 } = user; // with a default
const { name: userName } = user; // rename
const { address: { city } = {} } = user; // nested, safely
const [first, second] = items;
const [first, ...rest] = items;
const [, , third] = items; // skip positions
function greet({ name, greeting = "Hi" }) { // destructure a parameter
return `${greeting}, ${name}`;
}Destructuring a function parameter is the pattern worth adopting. It makes the call site self-documenting and removes the "which argument was which?" problem entirely.
Spread and Rest
const merged = [...a, ...b];
const copy = [...items];
const obj = { ...defaults, ...overrides }; // later wins
const patched = { ...user, name: "New" }; // immutable update
function sum(...nums) { // rest β collects arguments
return nums.reduce((a, b) => a + b, 0);
}Spread is a shallow copy. { ...user } copies top-level properties; nested objects are still shared references. For a genuine deep copy, structuredClone(obj) is now built in and should be preferred over the old JSON.parse(JSON.stringify(obj)) trick, which silently destroys dates, undefined, and functions.
Optional Chaining and Nullish Coalescing
Two operators that between them removed a great deal of defensive code.
user?.address?.city // undefined instead of TypeError
user.getName?.() // only calls it if it exists
items?.[0] // safe index access
const name = user?.name ?? "Guest";?? versus || β this one matters daily:
const qty = 0;
qty || 10 // 10 β wrong, 0 is a valid quantity
qty ?? 10 // 0 β correct|| falls back on any falsy value: 0, "", false, NaN, null, undefined. ?? falls back only on null and undefined.
If a user deliberately entered 0, an empty string, or false, || throws their input away. Use ?? for default values unless you specifically want all falsy values to trigger the fallback.
Functions
function named(a, b) { return a + b; }
const arrow = (a, b) => a + b;
const single = x => x * 2;
const obj = () => ({ a: 1 }); // parentheses to return an object literal
const withDefault = (x = 10) => x;Arrow functions and this:
// regular function β `this` depends on how it is CALLED
const counter = {
count: 0,
brokenIncrement() {
setTimeout(function () {
this.count++; // `this` is not the counter
}, 100);
},
workingIncrement() {
setTimeout(() => {
this.count++; // arrow inherits `this` from the method
}, 100);
},
};An arrow function has no this of its own β it uses whatever this was in the surrounding scope where it was written. That is almost always what you want in a callback.
The rule: arrow functions for callbacks; regular functions for object methods that need dynamic this.
Async
async function getUser(id) {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
try {
const user = await getUser(1);
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}// sequential β 3 seconds if each takes 1
const a = await getA();
const b = await getB();
const c = await getC();
// parallel β 1 second
const [a, b, c] = await Promise.all([getA(), getB(), getC()]);
// parallel, tolerating failures
const results = await Promise.allSettled([getA(), getB()]);await in a loop is the most common async performance mistake. If the calls do not depend on each other, Promise.all is the answer:
// slow β one at a time
for (const id of ids) {
results.push(await fetchUser(id));
}
// fast β all at once
const results = await Promise.all(ids.map(fetchUser));fetch does not throw on HTTP errors. A 404 or a 500 resolves normally with res.ok === false. Only a network failure rejects. You must check res.ok yourself, and forgetting to is why so many apps try to parse an error page as JSON.
Objects
Object.keys(obj); // ['a', 'b']
Object.values(obj); // [1, 2]
Object.entries(obj); // [['a', 1], ['b', 2]]
Object.fromEntries(pairs); // back to an object
for (const [key, value] of Object.entries(obj)) { ... }
const { a, ...rest } = obj; // omit a property
structuredClone(obj); // real deep copyObject.entries combined with array methods is how you map or filter an object:
const doubled = Object.fromEntries(
Object.entries(prices).map(([k, v]) => [k, v * 2])
);Strings
`Hello ${name}, you are ${age}` // template literal
str.trim()
str.split(",")
arr.join(", ")
str.replaceAll("a", "b")
str.padStart(2, "0") // "5" β "05"
str.at(-1) // last character
str.includes("x")Modern Additions Worth Knowing
arr.at(-1) // last element, no arr.length - 1
Object.groupBy(items, x => x.type) // group into an object
structuredClone(obj) // deep copy, built in
arr.toSorted((a, b) => a - b) // sort without mutating
arr.toReversed() // reverse without mutatingtoSorted and toReversed are the non-mutating versions of sort and reverse, added specifically because the mutating originals caused so many bugs. Prefer them.
The Four Traps
1. == versus ===. Always use ===. The coercion rules for == are genuinely unpredictable β null == undefined is true, null == 0 is false, "" == 0 is true. The one accepted exception is x == null to check for both null and undefined at once.
2. sort() mutates and compares as strings. [10, 9, 1].sort() gives [1, 10, 9]. Always pass a comparator; copy first if you need the original.
3. this in a regular callback. Use an arrow function, which inherits this from the enclosing scope.
4. NaN !== NaN. NaN is the only value in JavaScript not equal to itself, so arr.indexOf(NaN) never finds it. Use Number.isNaN(x) to test, and arr.includes(NaN), which does handle it.
Print This Section
ARRAYS map=transform Β· filter=subset Β· find=one Β· reduce=collapse
forEach=side effects only Β· sort MUTATES and sorts as strings
[...arr].sort((a,b) => a-b)
DEFAULTS x ?? fallback NOT x || fallback (0 and "" are valid)
SAFE user?.address?.city obj.method?.()
ASYNC Promise.all(ids.map(fn)) NOT await inside a loop
fetch does NOT throw on 404 β check res.ok
EQUALITY === always. NaN !== NaN. Number.isNaN(x)
THIS arrow for callbacks Β· regular function for object methodsMost JavaScript that reads badly is not wrong β it is using forEach where map belongs, or || where ?? belongs. Those two choices alone account for a large share of review comments.
π Next in this collection: TypeScript Cheat Sheet: Types, Generics, and Utility Types, or return to The Complete Developer Cheat Sheet Collection.
Advertisement
π¬ DiscussionPowered by GitHub Discussions
Frequently Asked Questions

AI & Software Engineering Editorial Team
The AiTechWorlds editorial team writes and reviews in-depth guides on artificial intelligence, machine learning, prompt engineering, programming, and developer tools. Every article is fact-checked against primary sources and kept up to date for working developers and CS students.
Not sure yet? Ask AI about this article
Get an instant, unbiased AI summary of βJavaScript Cheat Sheet You'll Use Every Day (Array Methods, Async and Traps)β.
Advertisement
Related Articles
Bash Scripting Cheat Sheet (The First Line Every Script Needs)
A practical Bash scripting cheat sheet β variables, conditionals, loops, functions, and the set -euo pipefail line that turns silent failure into loud failure.
15 Coding Interview Patterns That Solve Most Problems
The 15 coding interview patterns that cover most problems β the signal that identifies each one, a minimal code skeleton, and a two-minute recognition table.
CSS and Tailwind Cheat Sheet: Flexbox, Grid and Centering Solved
A practical CSS and Tailwind cheat sheet β Flexbox vs Grid decision rules, every centering method, responsive breakpoints, and the specificity traps.
Data Structures and Big-O Cheat Sheet for Coding Interviews
A practical big O cheat sheet β the complexity ladder with real examples, data structure operation tables, and how to state your complexity in an interview.