Home› JavaScript› Complete Guide
Complete Guide

Complete JavaScript Tutorial

JavaScript runs everywhere — browsers, servers, mobile apps. This complete guide covers all 185 JavaScript tutorials on TheCodeForge, from the basics of the DOM to async/await, React and Node.js.

Learning Roadmap
Beginner → Learn variables, functions, DOM manipulation and events
Intermediate → Master async/await, closures, ES6+ and the event loop
Advanced → Build full applications with React, Node.js and modern tooling
185
Topics
45
Beginner
78
Intermediate
62
Advanced
Jump to section
JS Basics (16)Advanced JS (28)DOM (9)React.js (53)Node.js (31)TypeScript (16)HTML & CSS (16) (1)Basics (4)Runtimes (1)CSS (1)Browser (7)Bundlers (2)

JavaScript is the only language most developers cannot avoid, which means it is also the language most people learn by accretion — a framework here, a Stack Overflow answer there — without ever assembling the underlying model. That works for a long time and then produces a specific kind of confusion: code that behaves differently than it reads.

Four mechanisms account for nearly all of it. The event loop decides when your code runs. Closures decide what it can see. The this binding rules decide what it is operating on. Prototypes decide where properties come from. Learn those four and the language stops surprising you — including the parts frameworks are built on.

The event loop, and why setTimeout(fn, 0) is not immediate

JavaScript runs on one thread with a queue. Synchronous code runs to completion. Then every queued microtask runs — promise callbacks, queueMicrotask — including microtasks queued during that drain. Only then does one macrotask run: a timer callback, an I/O event, a DOM event.

That ordering explains a whole family of behaviours: why setTimeout(fn, 0) runs after every pending promise, why a long synchronous loop freezes the UI completely, and why await inside a loop serialises requests that you probably meant to run concurrently.

javascript
console.log('a');
setTimeout(() => console.log('b'), 0);          // macrotask
Promise.resolve().then(() => console.log('c')); // microtask
console.log('d');
// a, d, c, b

// Serial: each await waits for the previous request
for (const id of ids) results.push(await fetchOne(id));

// Concurrent: start them all, then wait
const results = await Promise.all(ids.map(fetchOne));

// Concurrent but tolerant of individual failures
const settled = await Promise.allSettled(ids.map(fetchOne));
const ok = settled.filter(r => r.status === 'fulfilled').map(r => r.value);
In practicePromise.all rejects as soon as any input rejects, and the other requests keep running with nobody listening. When partial success is acceptable — and it usually is for a dashboard or a batch — allSettled is the correct choice.

Equality, coercion, and the two comparisons worth using

== applies a coercion algorithm that produces results nobody memorises reliably. === compares type and value with no coercion. Use === everywhere, with one idiomatic exception: x == null is a concise check for both null and undefined.

The distinction between those two is worth being precise about, because modern syntax depends on it. undefined means never assigned; null means deliberately empty. ?? falls back only for those two, while || falls back for every falsy value — which is why count || 10 turns a legitimate zero into ten and count ?? 10 does not.

ExpressionResultWhy it matters
0 == ''trueCoercion to number — the reason to avoid ==
[] == falsetrueArray to primitive, then to number
NaN === NaNfalseUse Number.isNaN, never an equality check
0 || 1010Falsy fallback swallows a valid zero
0 ?? 100Nullish fallback — almost always what you meant
typeof null'object'A well-known language bug, kept for compatibility

Closures are the language's most-used feature

A closure is a function that retains access to the variables of the scope it was created in — the variables themselves, not copies of their values. That distinction is the entire explanation for the classic loop puzzle, and for why let fixes it: var creates one function-scoped binding shared by every callback, while let creates a fresh binding per iteration.

Closures are also the mechanism behind most patterns you already use: module privacy, memoisation, debounce and throttle, React hooks holding state between renders, and every callback that remembers something from where it was defined.

javascript
// Debounce: the timer id lives in the closure, private to each instance
function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}

// Throttle: allow at most one call per interval
function throttle(fn, ms) {
  let last = 0;
  return (...args) => {
    const now = Date.now();
    if (now - last >= ms) { last = now; fn(...args); }
  };
}

// Debounce a search box (wait for quiet); throttle a scroll handler
// (steady rate). Using the wrong one is a common performance bug.

Modules, bundling and what actually ships

ES modules are static: imports are resolved before execution, which is what makes tree shaking possible — a bundler can prove a named export is unused and drop it. CommonJS require is a synchronous function call resolved at runtime, so it cannot be analysed the same way. That single difference explains most bundler behaviour and most of the interop friction between the two.

It also has a practical consequence worth carrying into code review: a default export of a large object, or a barrel file re-exporting an entire library, defeats tree shaking and can put hundreds of kilobytes into a bundle for one function. Named imports from the specific module are not a style preference — they are what lets the bundler remove what you do not use.

Frequently Asked Questions

var, let or const?
const by default, let when you must reassign, var never in new code. const prevents rebinding, not mutation — a const object's properties can still change, which is the point people most often misunderstand.
Do I need to learn JavaScript before a framework?
Enough of it, yes. Closures, this, promises and array methods appear in every framework's API, and debugging React or Vue without them means every problem looks like framework magic. A week on the fundamentals saves months of confusion.
What is the difference between null and undefined in practice?
undefined is the absence the language produces — an unassigned variable, a missing property, a function with no return. null is the absence you chose. APIs and databases usually return null; JavaScript itself produces undefined. Use ?? and ?. to handle both without accidentally catching zero or empty string.
Is TypeScript worth it for a small project?
Usually yes, and the cost is lower than people expect — you can adopt it file by file. The return is proportional to how long the code lives and how many people touch it. For a genuinely one-off script, plain JavaScript with JSDoc annotations gets you most of the editor benefit for none of the build setup.
Why does my async function return a Promise instead of the value?
Because that is what async means: the function always returns a promise, and await is how you unwrap it. If you are seeing Promise { <pending> }, a caller forgot to await — which is also why a missing await produces silent wrong behaviour rather than an error.
How much do I need to know about bundlers?
Enough to read the output: what ended up in the bundle, how large it is, and which import pulled in something unexpected. Bundle analysis is the highest-value hour in frontend performance work, and it needs no deep knowledge of the bundler's internals.

JS Basics

Advanced JS

DOM

React.js

Introduction to React Intermediate React Components and Props Intermediate React State Management Intermediate React Hooks — useState and useEffect Intermediate React useContext and useReducer Intermediate React useMemo and useCallback Advanced React Router Intermediate React Forms and Controlled Components Intermediate React Context API Intermediate React Performance Optimisation Advanced Redux with React Advanced React Testing with Jest Advanced Next.js Basics Intermediate React Custom Hooks Advanced React Lifecycle Methods Intermediate React Error Boundaries Advanced React Suspense and Lazy Loading Advanced React Server Components Advanced React 19 New Features Intermediate Next.js 16: Every New Feature Explained with Code Examples Advanced Partial Prerendering in Next.js 16 — The Complete Guide Advanced Advanced shadcn/ui Patterns Every Developer Should Know in 2026 Advanced I Built a SaaS in 48 Hours Using Only v0 + Cursor AI Advanced Building Type-Safe Forms with Zod, React Hook Form & Next.js 16 Advanced 10 Common Next.js 16 App Router Mistakes (And How to Fix Them) Intermediate Supabase Auth with Next.js 16 — The Complete 2026 Guide Advanced tRPC v11 + Next.js 16: Complete Setup and Best Practices Advanced How to Build an AI Agent with Next.js, LangChain & Supabase Advanced Next.js 16 Caching Strategies Explained: The 2026 Guide Advanced How to Build a Design System with shadcn/ui, Tailwind & Radix Advanced v0 + shadcn/ui: Build 5 Production Components (With Full Code) Advanced Prisma ORM Best Practices with Next.js 16 in 2026 Advanced React Server Components Performance Deep Dive (2026) Advanced Server Actions vs tRPC in 2026: When to Use Which? Intermediate Building Production-Grade AI Features in Next.js 16 Advanced How to Build Your Own AI Coding Assistant with Next.js 16, OpenAI & RAG (2026 Stack) Advanced The New T3 Stack in 2026 – Complete Updated Guide Advanced 10 Advanced shadcn/ui Tricks Most Developers Don't Know Advanced How to Fix Next.js 16 Hydration Errors Once and For All Intermediate Next.js 16 + React 19 Complete Migration Guide Advanced Advanced Error Handling & Logging in Next.js 16 Applications Advanced How I Generate 50+ shadcn Components Faster with AI Advanced Creating Reusable Component Libraries with shadcn/ui Advanced Building an AI SaaS from Scratch with Next.js 16 Advanced Building Multi-Agent AI Systems with Next.js and LangGraph Advanced Full-Stack Type Safety in 2026 – The Ultimate Guide Advanced How I Generate 50+ shadcn Components Automatically with AI Advanced React Node OpenSSL Error Fix Intermediate React Maximum Update Depth Fix Intermediate React Unique Key Prop Warning Fix Beginner React Unmounted State Update Fix Intermediate Next.js Hydration Mismatch Fix Intermediate React Invalid Hook Call Fix Intermediate

Node.js

TypeScript

HTML & CSS

Basics

Runtimes

CSS

Browser

Bundlers

Interview prep
→JavaScript Interview Questions
Also Explore
Web Platform 9 tutorials → DevOps 310 tutorials → Database 144 tutorials → Interview 77 tutorials → Frontend 13 tutorials → Testing 12 tutorials →
Start from the beginning

Every tutorial starts with a plain-English analogy — then real code, then interview questions.

Browse JavaScript Tutorials →