| |

JavaScript 73 🧬 Cheatsheet

⏱️ Estimated read: 7 min | |

This chapter is a condensed reference for the JavaScript language and its runtime environment. It is organized for lookup, not for reading. Each table covers one topic, and each entry is a fact that has a precise answer. The entries are drawn from the ECMAScript specification, the MDN documentation, and the behaviors that are verified by running the code. Where a behavior is version-dependent or runtime-dependent, the table says so explicitly.

Key point: JavaScript’s quirks are not random. They follow from the specification, and the specification is consistent. The == operator coerces, the this binding depends on the call site, and the event loop processes microtasks before macrotasks. Knowing the rule is faster than memorizing the exception.


Types and Coercion

ExpressionResultReason
typeof null"object"Historical bug, preserved for compatibility
typeof undefined"undefined"—
typeof function(){}"function"Functions are callable objects
typeof []"object"Arrays are objects
typeof NaN"number"NaN is a numeric value
null == undefinedtrueLoose equality treats them as equal
null === undefinedfalseDifferent types
NaN === NaNfalseNaN is not equal to anything
Object.is(NaN, NaN)trueSameValue algorithm
[] + []""Both convert to empty string
[] + {}"[object Object]"Array to string + object to string
{} + []0 (as statement)Block + unary plus on empty array
"5" - 23Subtraction coerces to number
"5" + 2"52"Addition with string is concatenation

Falsy Values

ValueFalsy
falseYes
0, -0, 0nYes
""Yes
nullYes
undefinedYes
NaNYes
[], {}, "0", "false"No

Variables and Scope

KeywordScopeHoistedTDZReassignable
varFunctionYes (initialized undefined)NoYes
letBlockYes (uninitialized)YesYes
constBlockYes (uninitialized)YesNo
ConceptBehavior
TDZAccessing a let/const before declaration throws ReferenceError
Hoistingvar declarations move to top; function declarations are fully hoisted
Block scope{} creates a new scope for let/const
ClosureFunction retains access to its lexical scope after the outer function returns

Functions and this

Call Sitethis Value
obj.method()obj
fn() (strict mode)undefined
fn() (sloppy mode)global object
new Fn()new instance
fn.call(x)x
fn.apply(x, args)x
Arrow functionLexical this (from enclosing scope)
Event handlerElement that fired the event (non-arrow)
Function TypeHoistedthisargumentsnew
Function declarationYesDynamicYesYes
Function expressionNoDynamicYesYes
Arrow functionNoLexicalNoNo
Method shorthandNoDynamicYesNo

Arrays

MethodMutatesReturnsUse
pushYesNew lengthAdd to end
popYesRemoved elementRemove from end
shiftYesRemoved elementRemove from start
unshiftYesNew lengthAdd to start
spliceYesRemoved elementsAdd/remove anywhere
sliceNoNew arrayCopy portion
concatNoNew arrayMerge arrays
mapNoNew arrayTransform
filterNoNew arraySubset
reduceNoAccumulatorAggregate
findNoElement or undefinedFirst match
findIndexNoIndex or -1Index of first match
includesNoBooleanMembership
sortYesSame arraySort in place
reverseYesSame arrayReverse in place
// sort is lexicographic by default
[10, 9, 1].sort();          // [1, 10, 9]
[10, 9, 1].sort((a, b) => a - b); // [1, 9, 10]

Objects

OperationSyntax
Property accessobj.key or obj['key']
Optional chainingobj?.key?.nested
Nullish coalescingobj.key ?? 'default'
Destructuringconst { a, b: renamed } = obj
Spread{ ...obj, extra: 1 }
Shallow copy{ ...obj } or Object.assign({}, obj)
Deep copystructuredClone(obj)
KeysObject.keys(obj)
ValuesObject.values(obj)
EntriesObject.entries(obj)
FreezeObject.freeze(obj)
Check property'key' in obj or obj.hasOwnProperty('key')

Promises and Async

ConceptBehavior
Promise.resolve(x)Promise fulfilled with x
Promise.reject(e)Promise rejected with e
Promise.all([...])Resolves when all resolve; rejects on first rejection
Promise.allSettled([...])Resolves when all settle; never rejects
Promise.race([...])Settles with the first settled promise
Promise.any([...])Resolves on first fulfillment; rejects if all reject
async functionAlways returns a Promise
awaitSuspends until the promise settles
Unhandled rejectionLogged by the runtime; may terminate Node.js
// Promise.all: fails fast
await Promise.all([fetch(a), fetch(b)]); // rejects if either fails

// Promise.allSettled: never rejects
const results = await Promise.allSettled([fetch(a), fetch(b)]);
// [{ status: 'fulfilled', value }, { status: 'rejected', reason }]

Event Loop

QueuePriorityExamples
Call stackHighestSynchronous code
Microtask queueAfter each stack framePromise.then, queueMicrotask, MutationObserver
Macrotask queueAfter microtasks drainsetTimeout, setInterval, I/O, UI events
OrderExample
1console.log('sync')
2Promise.resolve().then(() => console.log('micro'))
3setTimeout(() => console.log('macro'), 0)
Outputsync, micro, macro
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
// Output: A, D, C, B

Iteration

ConstructUse
forGeneral loop
for...ofIterable values (arrays, strings, Maps, Sets)
for...inEnumerable property names (including inherited)
forEachArray iteration; no break
map/filter/reduceFunctional transforms
Array.from(iterable)Convert iterable to array
[...iterable]Spread iterable into array
// for...of does not work on plain objects
for (const value of [1, 2, 3]) { }        // ✅
for (const value of { a: 1, b: 2 }) { }   // ❌ not iterable
for (const key in { a: 1, b: 2 }) { }     // ✅ "a", "b"

Modules

SyntaxMeaning
export const x = 1Named export
export default xDefault export
export { a, b as c }Named exports with alias
import x from 'mod'Import default
import { a, b } from 'mod'Import named
import * as ns from 'mod'Import namespace
import('mod')Dynamic import (returns Promise)
AspectESMCommonJS
Syntaximport/exportrequire/module.exports
LoadingStatic, asynchronousDynamic, synchronous
Top-level thisundefinedmodule.exports
Live bindingsYesNo (copied values)
File extension.mjs or .js with "type": "module".cjs or .js with "type": "commonjs"

Error Handling

ConstructBehavior
try/catchCatches synchronous errors and await rejections
try/catch/finallyfinally runs regardless
throwThrows a value (usually an Error)
Error subclassesTypeError, RangeError, ReferenceError, SyntaxError
Error.causeWraps the original error (ES2022)
AggregateErrorGroups multiple errors (ES2021)
try {
  await riskyOperation();
} catch (err) {
  if (err instanceof TypeError) { /* handle */ }
  throw new Error('Wrapped', { cause: err });
} finally {
  cleanup();
}

Numbers and Math

ExpressionResult
0.1 + 0.20.30000000000000004
0.1 + 0.2 === 0.3false
Number.MAX_SAFE_INTEGER9007199254740991
Number.MIN_SAFE_INTEGER-9007199254740991
Number.isInteger(1.0)true
Number.isNaN(NaN)true
parseInt("08", 10)8
parseFloat("3.14abc")3.14
(0.1 + 0.2).toFixed(2)"0.30"
Math.round(0.5)1
Math.round(-0.5)-0
Number("")0
Number(" ")0
Number("abc")NaN

Destructuring and Defaults

PatternExample
Arrayconst [a, , b] = [1, 2, 3]
Objectconst { a, b } = { a: 1, b: 2 }
Renameconst { a: x } = { a: 1 }
Defaultconst { a = 10 } = {}
Restconst [a, ...rest] = [1, 2, 3]
Nestedconst { a: { b } } = { a: { b: 1 } }
Swap[a, b] = [b, a]

Visual

The Event Loop

┌──────────────────────────────────────────────────────────────┐
│  CALL STACK                                                  │
│  ┌─────────────────────────────────────────────────────────┐│
│  │ Synchronous code executes here                          ││
│  └──────────────────────────┬──────────────────────────────┘│
│                             │ Stack empty                    │
│                             ▼                                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │ MICROTASK QUEUE                                         ││
│  │ Promise.then, queueMicrotask, MutationObserver          ││
│  │ Drained completely before next macrotask                ││
│  └──────────────────────────┬──────────────────────────────┘│
│                             │ Microtasks empty               │
│                             ▼                                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │ MACROTASK QUEUE                                         ││
│  │ setTimeout, setInterval, I/O, UI events                 ││
│  │ One task per loop iteration                             ││
│  └─────────────────────────────────────────────────────────┘│
│                                                              │
│  Microtasks always run before the next macrotask.            │
│                                                              │
└──────────────────────────────────────────────────────────────┘

this Binding

┌──────────────────────────────────────────────────────────────┐
│  CALL SITE DETERMINES this                                   │
│                                                              │
│  obj.method()      → obj                                    │
│  fn()              → undefined (strict) or global (sloppy)  │
│  new Fn()          → new instance                            │
│  fn.call(x)        → x                                      │
│  () => this        → lexical this from enclosing scope      │
│                                                              │
│  Arrow functions do not have their own this.                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

== vs ===

┌──────────────────────────────────────────────────────────────┐
│  == (loose)                    === (strict)                  │
│                                                              │
│  Coerces types                 No coercion                   │
│  null == undefined → true      null === undefined → false   │
│  "5" == 5 → true               "5" === 5 → false           │
│  0 == false → true             0 === false → false          │
│  "" == 0 → true                "" === 0 → false             │
│                                                              │
│  Use === unless you specifically want null/undefined         │
│  to be treated as equal.                                     │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Promise Combinators

┌──────────────────────────────────────────────────────────────┐
│  Promise.all          All resolve → resolve                 │
│                       Any reject → reject                   │
│                                                              │
│  Promise.allSettled   All settle → resolve                  │
│                       Never rejects                         │
│                                                              │
│  Promise.race         First settle → settle                 │
│                       (resolve or reject)                   │
│                                                              │
│  Promise.any          First resolve → resolve               │
│                       All reject → AggregateError           │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Module Loading

┌──────────────────────────────────────────────────────────────┐
│  ESM                          COMMONJS                      │
│                                                              │
│  import x from 'mod'          const x = require('mod')      │
│  export default x             module.exports = x            │
│  export const y = 1           exports.y = 1                 │
│                                                              │
│  Static, async                Dynamic, sync                  │
│  Live bindings                Copied values                  │
│  Top-level await allowed      No top-level await             │
│                                                              │
│  ESM is the standard. CommonJS is legacy but still common.   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Summary

TopicCore Fact
typeof null"object" (historical bug)
NaN equalityNot equal to itself; use Number.isNaN
== vs ===== coerces; === does not
Falsy valuesfalse, 0, -0, 0n, "", null, undefined, NaN
var vs let vs constFunction vs block scope; TDZ for let/const
thisDetermined by call site; lexical for arrows
Array sortLexicographic by default; pass comparator
Promise.allFails fast on first rejection
Event loopMicrotasks before macrotasks
ESM vs CJSStatic/async vs dynamic/sync

Key takeaways:

  • typeof null returns "object". This is a bug from the first version of JavaScript that was never fixed because fixing it would break existing code. Checking for null requires value === null, not typeof .
  • NaN is not equal to itself. NaN === NaN is false. Use Number.isNaN(value) or Object.is(value, NaN) to test for NaN. The global isNaN coerces its argument, which produces surprising results for non-numeric values.
  • == coerces, === does not. The loose equality operator applies the abstract equality algorithm, which converts types before comparing. The strict equality operator compares both type and value. The only common use for == is x == null, which is true for both null and undefined.
  • this depends on the call site. The same function can have different this values depending on how it is called. Arrow functions are the exception: they capture this from the enclosing scope and cannot be rebound.
  • Microtasks run before macrotasks. Promises, queueMicrotask, and MutationObserver are microtasks. setTimeout, setInterval, I/O, and UI events are macrotasks. The event loop drains the microtask queue completely after each macrotask and after each synchronous execution.
  • Promise.all fails fast; Promise.allSettled never rejects. Use Promise.all when any failure should abort the operation. Use Promise.allSettled when every result is needed regardless of individual failures. Use Promise.any when the first success is sufficient.

Remember: JavaScript’s behavior is defined by the specification, and the specification is consistent even when the behavior looks arbitrary. The coercion rules, the this binding rules, the event loop ordering, and the module semantics all follow from a small number of principles. The cheatsheet is a lookup table for the facts, but the facts are connected. typeof null is a bug, but it is a bug that the specification preserves. this is dynamic, but it is dynamic in a predictable way. The event loop has two queues, and the order between them is fixed. Knowing the rule is faster than memorizing the exception.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!