JavaScript Quick Reference

Variables, functions, arrays, promises, DOM manipulation, Fetch API and ES6+ features.

Variables & Types

// Declaration — prefer const, use let when reassignment is needed
const API_URL = 'https://api.example.com';
let count = 0;
// var is function-scoped and hoisted — avoid in modern code

// Primitive types
typeof 'hello'       // 'string'
typeof 42            // 'number'
typeof true          // 'boolean'
typeof undefined     // 'undefined'
typeof null          // 'object' (legacy quirk)
typeof Symbol()      // 'symbol'
typeof 42n           // 'bigint'

// Type checking
Array.isArray([1,2])           // true
Number.isFinite(42)            // true
Number.isNaN(NaN)              // true
Number.isInteger(3.0)          // true

// Type conversion
String(42)                     // '42'
Number('42')                   // 42
Number('')                     // 0
Number('abc')                  // NaN
Boolean(0)                     // false
Boolean('')                    // false
Boolean(null)                  // false
Boolean(undefined)             // false
parseInt('42px', 10)           // 42
parseFloat('3.14rem')          // 3.14
Falsy valuesTruthy (everything else)
false, 0, -0, 0n, "", null, undefined, NaN"0", [], {}, "false", any non-zero number

Functions & Arrow Functions

// Function declaration (hoisted)
function add(a, b) {
  return a + b;
}

// Function expression
const multiply = function(a, b) {
  return a * b;
};

// Arrow function
const square = (x) => x * x;
const greet = (name) => `Hello, ${name}!`;
const sum = (a, b) => a + b;

// Multi-line arrow
const process = (data) => {
  const cleaned = data.trim();
  return cleaned.toUpperCase();
};

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

// Rest parameters
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

// Destructured parameters
function formatUser({ name, email, role = 'user' }) {
  return `${name} (${role}) — ${email}`;
}

// IIFE (Immediately Invoked)
(() => {
  const secret = 'encapsulated';
})();

Arrays

const arr = [1, 2, 3, 4, 5];

// Iteration (non-mutating)
arr.forEach((item, i) => console.log(i, item));
const doubled = arr.map(n => n * 2);              // [2, 4, 6, 8, 10]
const evens = arr.filter(n => n % 2 === 0);        // [2, 4]
const total = arr.reduce((sum, n) => sum + n, 0);  // 15
const first = arr.find(n => n > 3);                // 4
const idx = arr.findIndex(n => n > 3);             // 3
const allPositive = arr.every(n => n > 0);         // true
const hasEven = arr.some(n => n % 2 === 0);        // true
const flat = [[1,2],[3,4]].flat();                 // [1,2,3,4]

// Mutation
arr.push(6);          // Add to end → [1,2,3,4,5,6]
arr.pop();            // Remove from end → 6
arr.unshift(0);       // Add to start → [0,1,2,3,4,5]
arr.shift();          // Remove from start → 0
arr.splice(1, 2);     // Remove 2 items at index 1
arr.sort((a,b) => a - b);  // Numeric sort (ascending)

// Non-mutating creation
const copy = [...arr];
const merged = [...arr1, ...arr2];
const sliced = arr.slice(1, 3);       // Elements at index 1,2
const unique = [...new Set(arr)];     // Remove duplicates

// Destructuring
const [first, second, ...rest] = [10, 20, 30, 40];
// first=10, second=20, rest=[30,40]

// Array.from
Array.from({ length: 5 }, (_, i) => i);  // [0,1,2,3,4]
Array.from('hello');                       // ['h','e','l','l','o']

Objects

// Object literal
const user = {
  name: 'Alex',
  email: '[email protected]',
  greet() {
    return `Hi, I'm ${this.name}`;
  }
};

// Shorthand properties
const name = 'Alex';
const role = 'admin';
const obj = { name, role };  // { name: 'Alex', role: 'admin' }

// Computed property names
const key = 'status';
const config = { [key]: 'active' };  // { status: 'active' }

// Destructuring
const { name: userName, email, role: userRole = 'user' } = user;

// Spread and merge
const defaults = { theme: 'dark', lang: 'en' };
const prefs = { lang: 'de' };
const merged = { ...defaults, ...prefs };  // { theme:'dark', lang:'de' }

// Object methods
Object.keys(user);           // ['name', 'email', 'greet']
Object.values(user);         // ['Alex', '[email protected]', ...]
Object.entries(user);        // [['name','Alex'], ['email','...'], ...]
Object.assign({}, a, b);     // Merge (shallow)
Object.freeze(user);         // Make immutable (shallow)
Object.fromEntries(entries); // Entries array → object

// Optional chaining and nullish coalescing
const city = user?.address?.city ?? 'Unknown';
const port = config.port ?? 3000;

Promises & Async/Await

// Creating a promise
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));

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

// Async/await — cleaner syntax for promises
async function getUsers() {
  try {
    const res = await fetch('/api/users');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Failed:', err.message);
    throw err;
  }
}

// Parallel execution
const [users, posts] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json())
]);

// First to resolve
const fastest = await Promise.race([
  fetch('/api/primary'),
  fetch('/api/fallback')
]);

// All settled (no short-circuit on rejection)
const results = await Promise.allSettled([
  fetch('/api/a'),
  fetch('/api/b'),
  fetch('/api/c')
]);
// Each: { status: 'fulfilled', value } or { status: 'rejected', reason }

DOM Manipulation

// Selecting elements
const el = document.getElementById('app');
const btn = document.querySelector('.btn-primary');
const items = document.querySelectorAll('.item');   // NodeList
const itemsArr = [...document.querySelectorAll('.item')]; // Array

// Creating and inserting
const div = document.createElement('div');
div.className = 'card';
div.textContent = 'Hello';
div.innerHTML = '<span>Rich content</span>';
parent.appendChild(div);
parent.prepend(div);
sibling.after(div);
sibling.before(div);
parent.insertAdjacentHTML('beforeend', '<p>Added</p>');

// Removing
el.remove();
parent.removeChild(child);

// Attributes
el.getAttribute('data-id');
el.setAttribute('aria-label', 'Close');
el.removeAttribute('hidden');
el.dataset.id;                // data-id attribute
el.hasAttribute('disabled');

// Classes
el.classList.add('active');
el.classList.remove('active');
el.classList.toggle('active');
el.classList.contains('active');
el.classList.replace('old', 'new');

// Styles
el.style.color = 'var(--color-accent)';
el.style.display = 'none';
getComputedStyle(el).fontSize;

// Dimensions and position
el.getBoundingClientRect();   // { top, left, width, height, ... }
el.offsetWidth;               // Width including border
el.scrollTop;                 // Scroll position

Event Handling

// Add event listener
btn.addEventListener('click', (e) => {
  e.preventDefault();
  console.log('Clicked:', e.target);
});

// Remove listener (needs function reference)
function handler(e) { /* ... */ }
btn.addEventListener('click', handler);
btn.removeEventListener('click', handler);

// Event delegation — handle events on dynamic children
document.querySelector('.list').addEventListener('click', (e) => {
  const item = e.target.closest('.list-item');
  if (!item) return;
  console.log('Item clicked:', item.dataset.id);
});

// Common events
// click, dblclick, mouseenter, mouseleave
// keydown, keyup, keypress (deprecated)
// input, change, submit, focus, blur
// scroll, resize, load, DOMContentLoaded

// Keyboard events
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') closeModal();
  if (e.ctrlKey && e.key === 's') {
    e.preventDefault();
    save();
  }
});

// Custom events
const event = new CustomEvent('userLogin', { detail: { userId: 42 } });
el.dispatchEvent(event);
el.addEventListener('userLogin', (e) => console.log(e.detail.userId));

// Once option — auto-removes after first trigger
btn.addEventListener('click', handler, { once: true });

// Passive — improves scroll performance
el.addEventListener('touchstart', handler, { passive: true });

Fetch API

// GET request
const res = await fetch('https://api.example.com/users');
const data = await res.json();

// POST request
const res = await fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Alex', email: '[email protected]' })
});

// PUT request
await fetch(`/api/users/${id}`, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(updatedUser)
});

// DELETE request
await fetch(`/api/users/${id}`, { method: 'DELETE' });

// With authentication
await fetch('/api/data', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
});

// Upload file
const formData = new FormData();
formData.append('file', fileInput.files[0]);
await fetch('/api/upload', { method: 'POST', body: formData });

// Abort a request
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

try {
  const res = await fetch('/api/slow', { signal: controller.signal });
} catch (err) {
  if (err.name === 'AbortError') console.log('Request timed out');
}

// Response handling
res.ok              // true if status 200-299
res.status          // 404, 500, etc.
res.headers.get('Content-Type')
await res.text()    // Plain text
await res.json()    // Parse JSON
await res.blob()    // Binary data

ES6+ Features

Template literals

const msg = `Hello, ${name}! You have ${count} items.`;

const html = `
  <div class="card">
    <h2>${title}</h2>
    <p>${description}</p>
  </div>
`;

// Tagged templates
function highlight(strings, ...values) {
  return strings.reduce((result, str, i) =>
    `${result}${str}<mark>${values[i] || ''}</mark>`, '');
}

Destructuring

// Arrays
const [a, b, ...rest] = [1, 2, 3, 4];

// Objects
const { name, age, city = 'Unknown' } = person;

// Nested
const { address: { street, zip } } = user;

// Renaming
const { name: userName } = user;

// Function parameters
function render({ title, body, footer = '' }) { /* ... */ }

Modules

// Named exports
export const API_URL = '/api';
export function fetchData() { /* ... */ }

// Default export
export default class UserService { /* ... */ }

// Import
import UserService from './UserService.js';
import { API_URL, fetchData } from './config.js';
import * as utils from './utils.js';

// Dynamic import (code splitting)
const module = await import('./heavy-module.js');
module.doSomething();

Map, Set, WeakMap, WeakSet

// Map — key-value pairs (any key type)
const map = new Map();
map.set('key', 'value');
map.set(42, 'number key');
map.get('key');              // 'value'
map.has(42);                 // true
map.size;                    // 2
map.delete(42);
for (const [k, v] of map) { /* ... */ }

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

Iterators and generators

// Generator function
function* range(start, end, step = 1) {
  for (let i = start; i < end; i += step) {
    yield i;
  }
}

for (const n of range(0, 10, 2)) {
  console.log(n);  // 0, 2, 4, 6, 8
}

// Spread into array
const nums = [...range(1, 6)];  // [1, 2, 3, 4, 5]

Common Patterns

Debounce

function debounce(fn, delay = 300) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

const search = debounce((query) => fetchResults(query), 400);
input.addEventListener('input', (e) => search(e.target.value));

Throttle

function throttle(fn, limit = 300) {
  let waiting = false;
  return (...args) => {
    if (waiting) return;
    fn(...args);
    waiting = true;
    setTimeout(() => { waiting = false; }, limit);
  };
}

window.addEventListener('scroll', throttle(handleScroll, 100));

Deep clone

const clone = structuredClone(original);  // modern, handles circular refs
const shallow = { ...original };           // shallow copy only

Error handling pattern

class AppError extends Error {
  constructor(message, code, details = {}) {
    super(message);
    this.name = 'AppError';
    this.code = code;
    this.details = details;
  }
}

async function safeFetch(url) {
  try {
    const res = await fetch(url);
    if (!res.ok) throw new AppError('Request failed', res.status);
    return { data: await res.json(), error: null };
  } catch (err) {
    return { data: null, error: err };
  }
}

Local storage helpers

const storage = {
  get(key, fallback = null) {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : fallback;
    } catch { return fallback; }
  },
  set(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  },
  remove(key) {
    localStorage.removeItem(key);
  }
};