dev.rean.me
โญ FEATURED POSTjavascript

Complete JavaScript References & Tips with Code Examples

Comprehensive JavaScript reference guide covering variables, arrays, objects, DOM, async, ES6+ features, and practical tips with code examples.

2026-09-19 ยท 25 min read

Share:

Hello my friend! Welcome to the Complete JavaScript References & Tips guide on dev.rean.me!

JavaScript is the most popular programming language for building interactive web apps. In this guide, we cover all essential JavaScript syntax, built-in methods, ES6+ features, DOM manipulation, async patterns, and practical tips โ€” all grouped by category with clear code examples. Bookmark this page for quick daily reference! ๐Ÿš€


1. Variables & Data Types

JavaScript has three ways to declare variables and seven primitive data types.

KeywordRe-assign?Re-declare?ScopeUse When
constโŒ NoโŒ NoBlockDefault choice โ€” value won't change
letโœ… YesโŒ NoBlockValue will change later
varโœ… Yesโœ… YesFunctionโŒ Avoid in modern JS
// Primitives
const name    = "Rean";         // String
const age     = 25;             // Number
const isAdmin = true;           // Boolean
const nothing = null;           // null  (intentional empty)
let   missing;                  // undefined (not yet assigned)
const id      = Symbol("uid");  // Symbol (unique identifier)
const bigNum  = 9007199254740991n; // BigInt (very large integers)

// Reference types
const colors = ["Red", "Green", "Blue"]; // Array
const user   = { name: "Rean", age: 25 }; // Object
const greet  = () => "Hello!";            // Function

// Check type
console.log(typeof name);          // "string"
console.log(typeof age);           // "number"
console.log(Array.isArray(colors)); // true (don't use typeof for arrays!)

๐Ÿ’ก Tip: Always use const by default. Switch to let only when you need to reassign. Never use var โ€” it has confusing function-scope and hoisting behavior!


2. Operators Quick Reference

CategoryOperatorsDescription
Arithmetic+ - * / % **Math operations (** = exponent)
Comparison=== !== > < >= <=Strict comparison (use === always!)
Logical&& || !AND, OR, NOT
Nullish??Fallback for null or undefined only
Optional Chain?.Safe nested property access
Spread / Rest...Expand or collect values
Assignment= += -= *= /= ??=Assign and update values
Ternarycondition ? a : bInline if-else shorthand
// Strict equality (always use ===, never ==)
console.log(5 === "5"); // false โ€” correct!
console.log(5 == "5");  // true  โ€” type coercion, avoid!

// Nullish coalescing (only fallback for null/undefined)
const count = 0;
console.log(count ?? 10); // 0  โ€” 0 is valid!
console.log(count || 10); // 10 โ€” 0 is falsy, not what you want!

// Optional chaining (safe nested access)
const user = { profile: { name: "Bopha" } };
console.log(user?.profile?.name);    // "Bopha"
console.log(user?.address?.city);   // undefined (no crash!)

// Combine ?. and ?? for bulletproof access
const city = user?.address?.city ?? "Unknown";
console.log(city); // "Unknown"

// Exponentiation
console.log(2 ** 10); // 1024

๐Ÿ’ก Tip: Combine ?. (optional chaining) with ?? (nullish coalescing) for safe, crash-proof data access when working with API responses!


3. Control Flow (if, switch, ternary)

// if / else if / else
const score = 85;

if (score >= 90) {
  console.log("Grade: A");
} else if (score >= 80) {
  console.log("Grade: B");
} else if (score >= 70) {
  console.log("Grade: C");
} else {
  console.log("Grade: F");
}

// switch (great for exact value matching)
const day = "Monday";
switch (day) {
  case "Saturday":
  case "Sunday":
    console.log("Weekend! ๐ŸŽ‰");
    break;
  case "Monday":
    console.log("Start of work week.");
    break;
  default:
    console.log("Weekday.");
}

// Ternary operator (short inline if-else)
const age = 20;
const status = age >= 18 ? "Adult" : "Minor";
console.log(status); // "Adult"

// Nullish assignment (assign only if null/undefined)
let username = null;
username ??= "Guest";
console.log(username); // "Guest"

๐Ÿ’ก Tip: Use switch when matching one variable against many exact values. Use if/else for complex conditions with range checks or multiple variables!


4. Loops & Iteration

Loop TypeBest Used For
forKnown number of iterations, index needed
for...ofIterating array or string values cleanly
for...inIterating object keys
whileUnknown number of iterations (condition-based)
do...whileMust run at least once before checking condition
forEach()Array iteration with index callback
map()Transform array into new array
filter()Keep items matching condition
reduce()Accumulate array into single value
const fruits = ["Apple", "Banana", "Mango"];

// Standard for loop (when you need index)
for (let i = 0; i < fruits.length; i++) {
  console.log(`${i + 1}. ${fruits[i]}`);
}

// for...of (cleaner array iteration)
for (const fruit of fruits) {
  console.log(fruit);
}

// for...in (object keys)
const user = { name: "Rean", age: 25 };
for (const key in user) {
  console.log(`${key}: ${user[key]}`);
}

// while loop
let count = 0;
while (count < 3) {
  console.log(`Count: ${count}`);
  count++;
}

// forEach (best for side effects โ€” logging, DOM updates)
fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});

๐Ÿ’ก Tip: Use for...of for clean array iteration. Use forEach() when you need the index. Avoid for...in on arrays โ€” use it only for objects!


5. Functions Reference

// 1. Function Declaration (hoisted โ€” can call before defining)
function add(a, b) {
  return a + b;
}

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

// 3. Arrow Function (modern, concise โ€” no own `this`)
const subtract = (a, b) => a - b;

// 4. Default Parameters
function greet(name = "Friend") {
  return `Hello, ${name}!`;
}
console.log(greet());        // "Hello, Friend!"
console.log(greet("Rean")); // "Hello, Rean!"

// 5. Rest Parameters (collect extra args into array)
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

// 6. Immediately Invoked Function Expression (IIFE)
const result = (() => {
  return "Runs immediately!";
})();
console.log(result);

// 7. Higher-Order Function (function that accepts/returns function)
function applyTax(rate) {
  return (price) => price * (1 + rate);
}
const applyGst = applyTax(0.1);
console.log(applyGst(100)); // 110

๐Ÿ’ก Tip: Arrow functions do not have their own this โ€” they inherit this from surrounding scope. This makes them perfect for array callbacks but wrong for object methods!


6. Arrays โ€” Complete Method Reference

Mutating Methods (modify original array)

MethodDescriptionExample
push(item)Add to endarr.push(4)
pop()Remove from endarr.pop()
unshift(item)Add to beginningarr.unshift(0)
shift()Remove from beginningarr.shift()
splice(i, n)Remove/insert at indexarr.splice(1, 2)
sort()Sort in-place (strings!)arr.sort()
reverse()Reverse in-placearr.reverse()
fill(val)Fill with valuearr.fill(0)

Non-Mutating Methods (return new array)

MethodReturnsDescription
map(fn)New arrayTransform every item
filter(fn)New arrayKeep items matching condition
reduce(fn, init)Single valueAccumulate items
find(fn)Single item or undefinedFirst item matching condition
findIndex(fn)Index or -1Index of first match
includes(val)true / falseCheck if value exists
some(fn)true / falseAt least one item matches
every(fn)true / falseAll items match
flat(depth)New arrayFlatten nested arrays
flatMap(fn)New arraymap + flat in one step
slice(start, end)New arrayExtract portion of array
concat(...arr)New arrayMerge arrays together
join(sep)StringJoin items into string
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];

// map: double every number
const doubled = numbers.map(n => n * 2);
// [6, 2, 8, 2, 10, 18, 4, 12]

// filter: keep only numbers greater than 4
const bigOnes = numbers.filter(n => n > 4);
// [5, 9, 6]

// reduce: sum all numbers
const total = numbers.reduce((acc, n) => acc + n, 0);
// 31

// find: first number greater than 5
const firstBig = numbers.find(n => n > 5);
// 9

// some / every
console.log(numbers.some(n => n > 8));  // true
console.log(numbers.every(n => n > 0)); // true

// flat (flatten nested arrays)
const nested = [[1, 2], [3, [4, 5]]];
console.log(nested.flat());    // [1, 2, 3, [4, 5]]
console.log(nested.flat(2));   // [1, 2, 3, 4, 5]

// Sort numbers correctly! (default sort is alphabetical string order!)
const sorted = [...numbers].sort((a, b) => a - b);
// [1, 1, 2, 3, 4, 5, 6, 9]

๐Ÿ’ก Tip: sort() converts items to strings by default โ€” always pass a comparator (a, b) => a - b for numeric sorting! Also always [...arr].sort() to avoid mutating the original!


7. Objects โ€” Complete Reference

// Object literal syntax
const user = {
  name: "Rean",
  age: 25,
  city: "Phnom Penh",
  greet() {            // Method shorthand (ES6)
    return `Hi, I'm ${this.name}!`;
  }
};

// Property access
console.log(user.name);       // Dot notation (preferred)
const key = "city";
console.log(user[key]);       // Bracket notation (dynamic key)

// Object Destructuring
const { name, age, city = "Unknown" } = user; // default value!
console.log(name, age, city);

// Rename during destructuring
const { name: fullName } = user;
console.log(fullName); // "Rean"

// Spread operator (shallow clone & merge)
const updatedUser = { ...user, role: "Admin", age: 26 };

// Computed property keys
const field = "score";
const record = { [field]: 100 }; // { score: 100 }

// Object static methods
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj));    // ["a", "b", "c"]
console.log(Object.values(obj));  // [1, 2, 3]
console.log(Object.entries(obj)); // [["a",1], ["b",2], ["c",3]]

// Create object from entries
const clone = Object.fromEntries(Object.entries(obj));

// Freeze object (prevent mutations)
const config = Object.freeze({ apiUrl: "https://api.example.com" });
// config.apiUrl = "other"; // silently fails in sloppy mode!

// Check if property exists
console.log("name" in user);               // true
console.log(user.hasOwnProperty("name")); // true

๐Ÿ’ก Tip: Use Object.entries() + forEach() to iterate key-value pairs of an object! Use Object.freeze() for configuration objects that should never be mutated!


8. Destructuring & Spread/Rest Patterns

// โ”€โ”€ OBJECT DESTRUCTURING โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const person = { name: "Dara", age: 22, job: "Designer" };

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

// Rename + default value
const { name: userName, salary = 1000 } = person;

// Nested object destructuring
const data = { user: { profile: { city: "Siem Reap" } } };
const { user: { profile: { city } } } = data;

// โ”€โ”€ ARRAY DESTRUCTURING โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const [first, second, ...rest] = [10, 20, 30, 40, 50];
console.log(first);  // 10
console.log(second); // 20
console.log(rest);   // [30, 40, 50]

// Swap variables without temp variable!
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

// โ”€โ”€ FUNCTION PARAMETER DESTRUCTURING โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
function displayUser({ name, age, role = "User" }) {
  console.log(`${name} (${age}) โ€” ${role}`);
}
displayUser({ name: "Kiri", age: 28, role: "Admin" });

// โ”€โ”€ SPREAD OPERATOR โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = [...arr1, ...arr2];         // [1,2,3,4,5,6]
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combined = { ...obj1, ...obj2 };    // { a:1, b:2 }

// โ”€โ”€ REST PARAMETERS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
function logAll(label, ...items) {
  console.log(label, items);
}
logAll("Fruits:", "Apple", "Banana", "Mango");
// "Fruits:", ["Apple", "Banana", "Mango"]

๐Ÿ’ก Tip: Use destructuring in function parameters to make APIs self-documenting โ€” ({ name, age }) shows exactly what properties are expected!


9. String Methods Reference

MethodReturnsDescription
toUpperCase()StringConvert to UPPERCASE
toLowerCase()StringConvert to lowercase
trim()StringRemove leading/trailing whitespace
trimStart() / trimEnd()StringTrim one side only
includes(str)BooleanCheck substring exists
startsWith(str)BooleanCheck prefix
endsWith(str)BooleanCheck suffix
indexOf(str)NumberPosition of first match (or -1)
lastIndexOf(str)NumberPosition of last match
slice(start, end)StringExtract substring
substring(start, end)StringExtract substring (no negatives)
replace(search, rep)StringReplace first match
replaceAll(search, rep)StringReplace all matches
split(sep)ArraySplit into array
repeat(n)StringRepeat string n times
padStart(len, char)StringPad from beginning
padEnd(len, char)StringPad from end
charAt(index)StringCharacter at position
charCodeAt(index)NumberUnicode value of char
at(index)StringAccess char (supports negative index!)
const str = "  Hello, JavaScript World!  ";

// Clean input
console.log(str.trim()); // "Hello, JavaScript World!"

// Search
console.log(str.includes("JavaScript")); // true
console.log(str.startsWith("  Hello"));  // true

// Transform
console.log(str.trim().toUpperCase());          // "HELLO, JAVASCRIPT WORLD!"
console.log("hello world".replace("world", "JS")); // "hello JS"
console.log("a-b-c-d".split("-"));              // ["a","b","c","d"]

// Padding (useful for number formatting)
console.log("5".padStart(3, "0")); // "005"
console.log("7".padEnd(3, "-"));   // "7--"

// Access characters
const code = "JS2026";
console.log(code.at(0));   // "J"
console.log(code.at(-1));  // "6"  (negative index from end!)

// Template literal (multi-line & interpolation)
const name = "Rean";
const message = `Hello ${name}!
Welcome to JavaScript.`;

๐Ÿ’ก Tip: Use .at(-1) to safely access the last character without writing str[str.length - 1]. The at() method supports negative indexes!


10. Number & Math Reference

// Number methods
const n = 3.14159;
console.log(n.toFixed(2));      // "3.14" (returns string!)
console.log(n.toPrecision(4));  // "3.142"
console.log(Number.isInteger(42));     // true
console.log(Number.isFinite(1/0));     // false
console.log(Number.isNaN(NaN));        // true (safer than global isNaN!)
console.log(Number.parseInt("42px"));  // 42
console.log(Number.parseFloat("3.14cm")); // 3.14

// Convert to Number
console.log(Number("123"));   // 123
console.log(+"123");          // 123 (unary + shortcut)
console.log(parseInt("0xFF", 16)); // 255

// Math methods
console.log(Math.abs(-5));          // 5
console.log(Math.round(4.6));       // 5
console.log(Math.floor(4.9));       // 4
console.log(Math.ceil(4.1));        // 5
console.log(Math.max(3, 7, 1, 9)); // 9
console.log(Math.min(3, 7, 1, 9)); // 1
console.log(Math.pow(2, 8));        // 256
console.log(Math.sqrt(144));        // 12
console.log(Math.trunc(-4.9));      // -4 (remove decimal, toward zero)
console.log(Math.sign(-5));         // -1 (positive=1, zero=0, negative=-1)

// Random number in range [min, max]
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 100)); // random number 1โ€“100

๐Ÿ’ก Tip: Always use Number.isNaN() instead of global isNaN() โ€” global isNaN("hello") returns true which is misleading. Number.isNaN("hello") correctly returns false!


11. Date & Time Reference

// Create Date objects
const now   = new Date();                    // Current date/time
const date1 = new Date("2026-09-19");        // From ISO string
const date2 = new Date(2026, 8, 19, 21, 0); // year, month(0-indexed!), day, h, m

// Get components
console.log(now.getFullYear());  // 2026
console.log(now.getMonth());     // 0โ€“11 (0 = January!)
console.log(now.getDate());      // Day of month (1โ€“31)
console.log(now.getDay());       // Day of week (0 = Sunday)
console.log(now.getHours());     // 0โ€“23
console.log(now.getMinutes());   // 0โ€“59
console.log(now.getTime());      // Milliseconds since Unix epoch

// Format date (Intl.DateTimeFormat โ€” modern & locale-aware!)
const formatted = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
}).format(now);
console.log(formatted); // "September 19, 2026"

// Time difference
const start = Date.now();
// ... do something ...
const elapsed = Date.now() - start; // milliseconds elapsed

// Calculate days between dates
function daysBetween(date1, date2) {
  const msPerDay = 1000 * 60 * 60 * 24;
  return Math.round(Math.abs(date2 - date1) / msPerDay);
}

๐Ÿ’ก Tip: Remember getMonth() returns 0โ€“11 (January = 0). Always use Intl.DateTimeFormat for locale-aware, formatted date strings instead of manual string building!


12. DOM Manipulation Reference

// โ”€โ”€ SELECTING ELEMENTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const el = document.querySelector("#myId");       // By ID (returns 1)
const els = document.querySelectorAll(".card");    // By class (returns NodeList)
const byId = document.getElementById("myId");     // Fastest by ID
const byClass = document.getElementsByClassName("card"); // HTMLCollection

// โ”€โ”€ READING & MODIFYING CONTENT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.textContent = "New text content";       // Safe โ€” no HTML parsing
el.innerHTML   = "<strong>Bold</strong>";  // โš ๏ธ Avoid for user input (XSS risk!)

// โ”€โ”€ ATTRIBUTES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.setAttribute("href", "https://dev.rean.me");
el.getAttribute("href");
el.removeAttribute("disabled");
el.dataset.userId = "42"; // Access data-* attribute

// โ”€โ”€ CSS CLASSES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("open");     // Add if absent, remove if present
el.classList.contains("active"); // Returns true/false

// โ”€โ”€ INLINE STYLES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.style.color = "blue";
el.style.backgroundColor = "#f0f4ff"; // camelCase!

// โ”€โ”€ CREATING & INSERTING ELEMENTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const div = document.createElement("div");
div.className = "card";
div.textContent = "New Card";
document.body.appendChild(div);    // Add at end of body
document.body.prepend(div);        // Add at start
el.before(div);                    // Insert before el
el.after(div);                     // Insert after el
el.replaceWith(div);               // Replace el with div

// โ”€โ”€ REMOVING ELEMENTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.remove(); // Remove element from DOM

// โ”€โ”€ TRAVERSAL โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
el.parentElement;
el.children;            // HTMLCollection of child elements
el.firstElementChild;
el.lastElementChild;
el.nextElementSibling;
el.previousElementSibling;
el.closest(".container"); // Nearest ancestor matching selector

๐Ÿ’ก Tip: Always use textContent instead of innerHTML when inserting user-provided text to avoid XSS (Cross-Site Scripting) vulnerabilities!


13. Events Reference

Common Event Types

CategoryEvents
Mouseclick, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleave
Keyboardkeydown, keyup, keypress
Formsubmit, change, input, focus, blur, reset
Windowload, DOMContentLoaded, resize, scroll, beforeunload
Touchtouchstart, touchmove, touchend
CustomCustomEvent โ€” dispatch your own events
// Add event listener
const btn = document.querySelector("#myBtn");

btn.addEventListener("click", (event) => {
  event.preventDefault();     // Prevent default browser action (e.g. form submit)
  event.stopPropagation();    // Stop event bubbling up to parent
  console.log("Clicked!", event.target);
});

// Remove event listener (must use named function reference!)
function handleClick(e) {
  console.log("Clicked!");
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);

// Event delegation (one listener for many children โ€” very efficient!)
document.querySelector("#list").addEventListener("click", (event) => {
  if (event.target.matches("li")) {
    console.log("List item clicked:", event.target.textContent);
  }
});

// Keyboard events
document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") console.log("ESC pressed");
  if (event.ctrlKey && event.key === "s") {
    event.preventDefault();
    console.log("Ctrl+S captured!");
  }
});

// Wait for DOM ready before selecting elements
document.addEventListener("DOMContentLoaded", () => {
  console.log("DOM fully parsed and ready!");
});

// Dispatch custom event
const myEvent = new CustomEvent("userLogin", { detail: { userId: 42 } });
document.dispatchEvent(myEvent);
document.addEventListener("userLogin", (e) => {
  console.log("User logged in:", e.detail.userId);
});

๐Ÿ’ก Tip: Use event delegation (one listener on a parent) instead of attaching listeners to every child element โ€” this is much better for performance and handles dynamically added elements automatically!


14. Async JavaScript โ€” Promises & async/await

// โ”€โ”€ PROMISE BASICS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const myPromise = new Promise((resolve, reject) => {
  const success = true;
  if (success) {
    resolve("Data loaded!");
  } else {
    reject(new Error("Something went wrong"));
  }
});

myPromise
  .then(result => console.log(result))      // "Data loaded!"
  .catch(error => console.error(error))
  .finally(() => console.log("Done!"));     // Always runs

// โ”€โ”€ ASYNC/AWAIT (modern, cleaner promise syntax) โ”€โ”€
async function fetchUser(id) {
  try {
    const response = await fetch(`https://api.example.com/users/${id}`);

    if (!response.ok) {
      throw new Error(`HTTP Error! Status: ${response.status}`);
    }

    const user = await response.json();
    return user;
  } catch (error) {
    console.error("Fetch failed:", error.message);
    return null;
  } finally {
    console.log("Fetch completed.");
  }
}

// โ”€โ”€ PARALLEL EXECUTION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Run multiple requests at the same time (much faster!)
const [users, products] = await Promise.all([
  fetch("/api/users").then(r => r.json()),
  fetch("/api/products").then(r => r.json())
]);

// Promise.allSettled (continue even if some fail)
const results = await Promise.allSettled([
  fetch("/api/users"),
  fetch("/api/unknown-endpoint")
]);
results.forEach(result => {
  if (result.status === "fulfilled") console.log(result.value);
  else console.error(result.reason);
});

// Promise.race (first settled wins)
const fastest = await Promise.race([
  fetch("/api/fast"),
  fetch("/api/slow")
]);

๐Ÿ’ก Tip: Use Promise.all() when you want to run multiple async operations in parallel (not sequentially). It's much faster than chaining multiple await calls one after another!


15. Error Handling

// try / catch / finally
try {
  const data = JSON.parse("invalid json{{{");
  console.log(data);
} catch (error) {
  console.error("Parse error:", error.message); // Parse error: ...
  console.log(error instanceof SyntaxError);    // true
} finally {
  console.log("This always runs!");
}

// Throw custom errors
function divide(a, b) {
  if (b === 0) throw new RangeError("Cannot divide by zero!");
  return a / b;
}

// Custom Error class
class ApiError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.name = "ApiError";
    this.statusCode = statusCode;
  }
}

try {
  throw new ApiError("Not Found", 404);
} catch (error) {
  if (error instanceof ApiError) {
    console.log(`${error.statusCode}: ${error.message}`);
  }
}

// Error types
// SyntaxError โ€” invalid JSON, parse errors
// TypeError   โ€” wrong data type
// RangeError  โ€” value out of allowed range
// ReferenceError โ€” undefined variable access

๐Ÿ’ก Tip: Create custom Error subclasses for domain-specific errors (like ApiError, ValidationError). This makes instanceof checks easy and error handling much cleaner!


16. ES6+ Modern Features Reference

// โ”€โ”€ CLASSES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
class Animal {
  #sound; // Private field (ES2022)

  constructor(name, sound) {
    this.name = name;
    this.#sound = sound;
  }

  speak() {
    return `${this.name} says ${this.#sound}!`;
  }

  static create(name, sound) { // Static factory method
    return new Animal(name, sound);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name, "Woof");
  }

  fetch() {
    return `${this.name} fetches the ball!`;
  }
}

const dog = new Dog("Rex");
console.log(dog.speak());  // "Rex says Woof!"
console.log(dog.fetch());  // "Rex fetches the ball!"
console.log(dog instanceof Animal); // true

// โ”€โ”€ MODULES (ES Modules) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// utils.js โ€” named exports
export const formatDate = (date) =>
  new Intl.DateTimeFormat("en-US").format(date);
export const clamp = (val, min, max) =>
  Math.min(Math.max(val, min), max);

// config.js โ€” default export
export default { apiUrl: "https://api.example.com" };

// main.js โ€” import
import config from "./config.js";
import { formatDate, clamp } from "./utils.js";
import * as utils from "./utils.js"; // import all as namespace

// โ”€โ”€ SYMBOLS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const uniqueId = Symbol("id");
const obj = { [uniqueId]: 42 };
// Symbol keys don't appear in for...in or Object.keys()!

// โ”€โ”€ GENERATORS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
function* counter(start = 0) {
  while (true) {
    yield start++;
  }
}
const gen = counter(1);
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

๐Ÿ’ก Tip: Use private class fields (#field) for true encapsulation! Unlike underscore convention (_field), #field is actually inaccessible from outside the class at the JavaScript engine level!


17. LocalStorage & SessionStorage

// localStorage โ€” persists after browser close
// sessionStorage โ€” cleared when tab is closed

// Store data (must stringify objects!)
localStorage.setItem("username", "Rean");
localStorage.setItem("user", JSON.stringify({ name: "Rean", role: "Admin" }));

// Read data
const username = localStorage.getItem("username");
const user = JSON.parse(localStorage.getItem("user") ?? "null");

// Remove data
localStorage.removeItem("username");

// Clear all storage
localStorage.clear();

// Helper class for safe JSON storage
class Storage {
  static get(key, fallback = null) {
    try {
      return JSON.parse(localStorage.getItem(key)) ?? fallback;
    } catch {
      return fallback;
    }
  }

  static set(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  }

  static remove(key) {
    localStorage.removeItem(key);
  }
}

// Usage
Storage.set("settings", { theme: "dark", lang: "en" });
const settings = Storage.get("settings", { theme: "light", lang: "en" });

๐Ÿ’ก Tip: Always wrap JSON.parse(localStorage.getItem(key)) in a try/catch โ€” if the stored value is corrupted or not valid JSON, it will throw a SyntaxError and crash your app!


18. Useful Utility Patterns & One-Liners

// โ”€โ”€ ARRAY UTILITIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Remove duplicates
const unique = [...new Set([1, 2, 2, 3, 3, 4])]; // [1,2,3,4]

// Shuffle array (Fisher-Yates)
const shuffle = arr =>
  [...arr].sort(() => Math.random() - 0.5);

// Chunk array into groups
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) },
    (_, i) => arr.slice(i * size, i * size + size));
console.log(chunk([1,2,3,4,5], 2)); // [[1,2],[3,4],[5]]

// Flatten deeply nested array
const flatDeep = arr => arr.flat(Infinity);

// Range of numbers
const range = (start, end, step = 1) =>
  Array.from({ length: Math.ceil((end - start) / step) },
    (_, i) => start + i * step);
console.log(range(0, 10, 2)); // [0, 2, 4, 6, 8]

// โ”€โ”€ OBJECT UTILITIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Deep clone (modern!)
const deepClone = obj => structuredClone(obj);

// Omit keys from object
const omit = (obj, keys) =>
  Object.fromEntries(Object.entries(obj)
    .filter(([k]) => !keys.includes(k)));

// Pick specific keys
const pick = (obj, keys) =>
  Object.fromEntries(keys.filter(k => k in obj).map(k => [k, obj[k]]));

// Group array of objects by key
const groupBy = (arr, key) =>
  arr.reduce((acc, item) => {
    const group = item[key];
    acc[group] = acc[group] ?? [];
    acc[group].push(item);
    return acc;
  }, {});

// โ”€โ”€ STRING UTILITIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Capitalize first letter
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);

// Slugify string for URLs
const slugify = str =>
  str.toLowerCase().trim()
     .replace(/[\s_]+/g, "-")
     .replace(/[^\w-]/g, "");

// Truncate text with ellipsis
const truncate = (str, max) =>
  str.length > max ? str.slice(0, max) + "โ€ฆ" : str;

// โ”€โ”€ NUMBER UTILITIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Clamp value between min and max
const clamp = (val, min, max) => Math.min(Math.max(val, min), max);

// Format number with commas
const formatNumber = n => n.toLocaleString("en-US");
console.log(formatNumber(1234567)); // "1,234,567"

// โ”€โ”€ TIMING UTILITIES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Sleep (pause execution)
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await sleep(1000); // Wait 1 second

// Debounce (delay execution until user stops typing)
function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}
const searchInput = document.querySelector("#search");
searchInput.addEventListener("input", debounce((e) => {
  console.log("Searching:", e.target.value);
}, 300));

// Throttle (allow max N calls per period)
function throttle(fn, limit) {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      fn(...args);
    }
  };
}
window.addEventListener("scroll", throttle(() => {
  console.log("Scroll event throttled!");
}, 200));

๐Ÿ’ก Tip: Use structuredClone(obj) for deep cloning objects instead of JSON.parse(JSON.stringify(obj)) โ€” it handles Dates, Maps, Sets, and circular references properly!


19. JavaScript Best Practices Summary

โœ… DoโŒ Avoid
Use const by defaultUsing var
Use === strict equalityUsing == loose equality
Use ?. optional chainingDirect nested property access on API data
Use Array.isArray()Using typeof to check arrays
Use textContent for textUsing innerHTML for user-provided text
Use Number.isNaN()Using global isNaN()
Use structuredClone() for deep copyUsing JSON.parse(JSON.stringify())
Handle errors with try/catchLeaving await calls unwrapped
Use event delegationAttaching listeners to every child
Use Promise.all() for parallelChaining await for independent requests
Use [...arr].sort()Mutating original array with .sort()
Use ES Modules (import/export)Using global variables everywhere

Summary Tag Cloud Directory

Happy coding and building awesome web applications with JavaScript! ๐Ÿš€