diff --git a/blog/assets/javascript-deep-dive-banner.jpg b/blog/assets/javascript-deep-dive-banner.jpg new file mode 100644 index 0000000..9a5b984 Binary files /dev/null and b/blog/assets/javascript-deep-dive-banner.jpg differ diff --git a/blog/authors.yml b/blog/authors.yml index 0fd3987..657d153 100644 --- a/blog/authors.yml +++ b/blog/authors.yml @@ -1,3 +1,20 @@ +ajay-dhangar: + name: Ajay Dhangar + title: Founder of CodeHarborHub + url: https://ajay-dhangar.github.io/ + image_url: https://avatars.githubusercontent.com/u/99037494?v=4 + email: ajaydhangar49@gmail.com + page: true # Turns the feature on + description: > + A passionate developer who loves to code and build new things. I am a Full Stack Developer and a Cyber Security, ML & AI Enthusiast. I am also a Technical Content Writer and a Speaker. I love to share my knowledge with the community. I am the Founder of CodeHarborHub. I am also a Technical Content Writer at GeeksforGeeks. I am a Girl Script Summer of Code 2024 Project Manager (PA). + + socials: + x: CodesWithAjay + linkedin: ajay-dhangar + github: ajay-dhangar + stackoverflow: 18530900 + newsletter: https://ajay-dhangar.github.io + yangshun: name: Yangshun Tay title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd diff --git a/blog/core-modern-javascript-deep-dives.md b/blog/core-modern-javascript-deep-dives.md new file mode 100644 index 0000000..ced5ed1 --- /dev/null +++ b/blog/core-modern-javascript-deep-dives.md @@ -0,0 +1,559 @@ +--- +slug: core-modern-javascript-deep-dives +title: "Core & Modern JavaScript: The Ultimate Deep Dive Guide" +authors: [ajay-dhangar] +tags: [javascript, webdev, architecture, performance, programming] +keywords: [javascript event loop, closures, promises, async await, prototypes, garbage collection, v8 engine, proxies, functional programming, web workers] +image: ./assets/javascript-deep-dive-banner.jpg +date: 2026-09-03 +--- + +If you want to move from writing basic JavaScript to architecting high-performance applications, you need a crystal-clear mental model of what happens under the hood. + +In this comprehensive guide, we unpack **10 core concepts** of modern JavaScript—complete with execution mechanics, visual architecture diagrams, production code patterns, and V8 optimization secrets. + +![JavaScript Core Architecture Banner](./assets/javascript-deep-dive-banner.jpg) + + + +## 1. Understanding the Event Loop: Microtasks, Macrotasks, and Call Stack Visualized + +If you ask ten JavaScript developers how the asynchronous execution model works, nine will tell you *"it handles async operations using callbacks."* That explanation misses the mechanical beauty of how JavaScript achieves non-blocking execution despite being **single-threaded**. + +### The Call Stack vs. Event Loop Architecture + +JavaScript operates on a **single call stack**. When you execute a function, it pushes a frame onto the stack. When the function returns, it pops off. + +To handle asynchronous operations without freezing the main UI thread, the browser runtime (V8, JavaScriptCore, SpiderMonkey) offloads work to **Web APIs** and coordinates execution using two queues: +1. **Microtask Queue** (High Priority) +2. **Macrotask Queue / Task Queue** (Standard Priority) + +```mermaid +flowchart TD + A[Call Stack Execution] --> B{Call Stack Empty?} + B -- No --> A + B -- Yes --> C[Flush Microtask Queue] + C --> D{Microtask Queue Empty?} + D -- No --> C + D -- Yes --> E[Render / Reflow Phase] + E --> F[De-queue ONE Macrotask] + F --> A + +``` + +### Microtask vs. Macrotask Execution Order + +The Event Loop follows a strict execution precedence: + +1. Execute all synchronous code on the **Call Stack**. +2. Once the Call Stack is empty, process **ALL jobs in the Microtask Queue** until it is completely cleared. +3. Allow the engine to perform layout rendering and paint recalculation if needed. +4. Pick **ONE job from the Macrotask Queue** and push it onto the Call Stack. +5. Repeat. + +| Queue Type | Operations | +| --- | --- | +| **Microtasks** | `Promise.then / catch / finally`, `queueMicrotask()`, `MutationObserver`, `process.nextTick` (Node.js) | +| **Macrotasks** | `setTimeout`, `setInterval`, `setImmediate`, `requestAnimationFrame`, I/O, UI Rendering | + +### Event Loop Execution Walkthrough + +Predict the exact output order of the following snippet: + +```javascript +console.log('1: Sync Start'); + +setTimeout(() => { + console.log('2: Macrotask (setTimeout)'); +}, 0); + +Promise.resolve().then(() => { + console.log('3: Microtask 1'); +}).then(() => { + console.log('4: Microtask 2'); +}); + +queueMicrotask(() => { + console.log('5: Microtask 3'); +}); + +console.log('6: Sync End'); + +``` + +**Output Breakdown:** + +```text +1: Sync Start +6: Sync End +3: Microtask 1 +4: Microtask 2 +5: Microtask 3 +2: Macrotask (setTimeout) + +``` + +## 2. Mastering JavaScript Closures: Real-World Use Cases + +A **closure** is created when a function is bundled together with references to its surrounding state (its **lexical environment**). Closures allow an inner function to retain access to an outer function's scope even after the parent function has finished executing. + +```mermaid +graph LR + subgraph Global Scope + G[Global Variables] + end + subgraph Outer Scope + O[Lexical Environment Record] + end + subgraph Inner Closure Scope + I[Inner Function Execution Context] + end + + I -->|Retains Reference| O + O -->|Delegates Search| G + +``` + +### Production Patterns Using Closures + +#### Pattern 1: Encapsulating Private Data + +Before native `#private` class fields, closures provided private state encapsulation: + +```javascript +function createSecureStore(initialBalance) { + // Private variables inaccessible from external scopes + let balance = initialBalance; + const transactionHistory = []; + + function logTransaction(type, amount) { + transactionHistory.push({ + type, + amount, + timestamp: new Date().toISOString(), + }); + } + + return { + deposit(amount) { + if (amount <= 0) throw new Error('Invalid deposit amount'); + balance += amount; + logTransaction('DEPOSIT', amount); + return balance; + }, + withdraw(amount) { + if (amount > balance) throw new Error('Insufficient funds'); + balance -= amount; + logTransaction('WITHDRAWAL', amount); + return balance; + }, + getHistory() { + return [...transactionHistory]; // Immutable snapshot + } + }; +} + +const myAccount = createSecureStore(1000); +myAccount.deposit(500); +console.log(myAccount.balance); // undefined +console.log(myAccount.getHistory()); // 1 transaction record + +``` + +#### Pattern 2: Memoization (Caching Expensive Computations) + +```javascript +function memoize(fn) { + const cache = new Map(); + + return function (...args) { + const key = JSON.stringify(args); + if (cache.has(key)) { + return cache.get(key); + } + + const result = fn.apply(this, args); + cache.set(key, result); + return result; + }; +} + +const factorial = memoize((n) => { + if (n === 0 || n === 1) return 1; + return n * factorial(n - 1); +}); + +console.time('First Run'); +factorial(100); // Computed and saved in closure state +console.timeEnd('First Run'); + +console.time('Second Run'); +factorial(100); // Instant lookup from closure cache +console.timeEnd('Second Run'); + +``` + +## 3. Promises, Async/Await, and Error Handling Best Practices + +Promises represent values that will settle in the future. They transition through three explicit states: + +```mermaid +stateDiagram-v2 + [*] --> Pending + Pending --> Fulfilled : resolve(value) + Pending --> Rejected : reject(error) + Fulfilled --> [*] + Rejected --> [*] + +``` + +### Sequential Waterfalls vs. Concurrent Parallel Execution + +#### ❌ Anti-Pattern: Sequential Fetch Waterfall + +```javascript +async function fetchDashboardSequential(userId) { + const user = await fetchUser(userId); // Takes 300ms + const posts = await fetchPosts(userId); // Takes 400ms + const stats = await fetchAnalytics(userId); // Takes 200ms + return { user, posts, stats }; // Total Time: ~900ms +} + +``` + +#### ✅ Refactored Pattern: Parallel Fetching with `Promise.allSettled` + +```javascript +async function fetchDashboardConcurrent(userId) { + try { + const [userResult, postsResult, statsResult] = await Promise.allSettled([ + fetchUser(userId), + fetchPosts(userId), + fetchAnalytics(userId), + ]); + + return { + user: userResult.status === 'fulfilled' ? userResult.value : null, + posts: postsResult.status === 'fulfilled' ? postsResult.value : [], + stats: statsResult.status === 'fulfilled' ? statsResult.value : null, + errors: [userResult, postsResult, statsResult] + .filter(res => res.status === 'rejected') + .map(res => res.reason), + }; + } catch (error) { + console.error('Fatal pipeline error:', error); + throw error; + } +} + +``` + +## 4. Prototypes, Inheritance, and the Prototype Chain + +JavaScript uses **prototypal inheritance**. Objects inherit directly from other objects via an internal link called `[[Prototype]]` (accessible via `Object.getPrototypeOf()` or `__proto__`). + +```mermaid +graph TD + A[instanceObj] -->|__proto__| B[CustomPrototype] + B -->|__proto__| C[Object.prototype] + C -->|__proto__| D[null] + +``` + +### Prototypal Constructor vs. ES6 Class Equivalent + +```javascript +// Function Constructor & Prototype Chain +function BaseComponent(id) { + this.id = id; +} + +BaseComponent.prototype.render = function () { + console.log(`Rendering ID: ${this.id}`); +}; + +function ButtonComponent(id, label) { + BaseComponent.call(this, id); + this.label = label; +} + +ButtonComponent.prototype = Object.create(BaseComponent.prototype); +ButtonComponent.prototype.constructor = ButtonComponent; + +ButtonComponent.prototype.click = function () { + console.log(`Clicked ${this.label}`); +}; + +const btn = new ButtonComponent('btn-01', 'Submit'); +btn.render(); // Derived via prototype lookup +btn.click(); + +``` + +--- + +## 5. Garbage Collection & Memory Leak Prevention in V8 + +V8 automates memory allocation and garbage collection using **Generational Garbage Collection** and **Mark-and-Sweep** algorithms. + +```mermaid +graph LR + subgraph V8 Memory Heap + subgraph Young Generation + A[Nursery / Eden] + B[Survivor Space] + end + subgraph Old Generation + C[Promoted Objects] + D[Large Object Space] + end + end + +``` + +### Common Memory Leaks and Solutions + +#### Leak: Dangling Global Event Listeners + +```javascript +// ❌ LEAK: Retains event listener and bound variables in memory +function attachListener() { + const payload = new Array(1000000).fill('data'); + window.addEventListener('resize', () => { + console.log(payload.length); + }); +} + +// ✅ FIX: Clean teardowns using AbortController +const controller = new AbortController(); + +window.addEventListener( + 'resize', + () => console.log('Resized cleanly'), + { signal: controller.signal } +); + +// Tear down listener when unmounting +controller.abort(); + +``` + +## 6. Modern Syntax Features: ES2024 to ES2026 + +### 1. `Object.groupBy()` + +Groups iterable items using custom callback keys: + +```javascript +const items = [ + { name: 'Laptop', category: 'tech', price: 1200 }, + { name: 'Chair', category: 'home', price: 250 }, + { name: 'Phone', category: 'tech', price: 800 }, +]; + +const grouped = Object.groupBy(items, (item) => item.category); +console.log(grouped.tech); + +``` + +### 2. Explicit Resource Management: `using` Declarations + +Automatically manages cleanup via `Symbol.dispose`: + +```javascript +class DatabaseConnection { + constructor(uri) { + console.log(`Connected to ${uri}`); + } + + query(sql) { + return `Executing: ${sql}`; + } + + [Symbol.dispose]() { + console.log('Closing database connection automatically...'); + } +} + +function runTransaction() { + // Automatically disposed when block exits + using db = new DatabaseConnection('postgres://localhost:5432/main'); + console.log(db.query('SELECT * FROM users')); +} + +runTransaction(); + +``` + +### 3. Change Array by Copy + +Perform immutable transformations on arrays: + +```javascript +const numbers = [3, 1, 4, 2]; + +const sorted = numbers.toSorted(); +const reversed = numbers.toReversed(); +const updated = numbers.with(2, 99); + +console.log(numbers); // [3, 1, 4, 2] (Preserved) +console.log(updated); // [3, 1, 99, 2] + +``` + +## 7. How V8 Executes Code: Ignition & TurboFan + +V8 processes source code through a multi-tier compilation pipeline: + +```mermaid +flowchart TD + A[JavaScript Code] --> B[Parser & AST Generator] + B --> C[Ignition Interpreter] + C --> D[Bytecode Execution] + D -->|Type Profiling| E{Hot Function?} + E -- Yes --> F[TurboFan JIT Compiler] + F --> G[Optimized Machine Code] + G -->|Type Invalidation| H[Deoptimization Bailout] + H --> C + +``` + +### V8 Optimization Tip: Keep Function Calls Monomorphic + +```javascript +function calculateTotal(item) { + return item.price * 1.18; +} + +// ✅ FAST: Monomorphic Calls (Identical Object Shape) +calculateTotal({ price: 100, name: 'Item A' }); +calculateTotal({ price: 200, name: 'Item B' }); + +// ❌ SLOW: Polymorphic/Megamorphic Calls (Causes JIT Deoptimization) +calculateTotal({ price: 100 }); +calculateTotal({ cost: 200, price: 50 }); + +``` + +## 8. Meta-Programming with Proxies and Reflect API + +The `Proxy` object wraps a target object, enabling custom interception traps for operations like property reads, assignments, and deletions. + +```mermaid +graph LR + Client[Caller Code] -->|Get / Set / Delete| P[Proxy Trap Handler] + P -->|Validate & Intercept| R[Reflect API Calls] + R -->|Mutate State| T[Target Object] + +``` + +### Reactive State Engine Example + +```javascript +function createReactiveSignal(target, onChange) { + return new Proxy(target, { + get(obj, prop, receiver) { + const value = Reflect.get(obj, prop, receiver); + if (typeof value === 'object' && value !== null) { + return createReactiveSignal(value, onChange); + } + return value; + }, + + set(obj, prop, value, receiver) { + const oldValue = obj[prop]; + if (oldValue !== value) { + const success = Reflect.set(obj, prop, value, receiver); + onChange(prop, value); + return success; + } + return true; + } + }); +} + +const state = createReactiveSignal( + { count: 0, user: { name: 'Ajay' } }, + (key, value) => console.log(`[UI Auto-Render]: Key "${String(key)}" updated to ${value}`) +); + +state.count++; +// [UI Auto-Render]: Key "count" updated to 1 + +state.user.name = 'Ajay Dhangar'; +// [UI Auto-Render]: Key "name" updated to Ajay Dhangar + +``` + +## 9. Functional Programming Principles in JavaScript + +Functional Programming relies on **pure functions**, **immutability**, and **function composition**. + +```mermaid +graph LR + Input[Raw Input Data] --> F1[Pure Function 1] + F1 -->|Immutable Data| F2[Pure Function 2] + F2 -->|Immutable Data| F3[Pure Function 3] + F3 --> Output[Transformed Output] + +``` + +### Composable Pipeline Pattern + +```javascript +const trim = (str) => str.trim(); +const toLowerCase = (str) => str.toLowerCase(); +const replaceSpaces = (str) => str.replace(/\s+/g, '-'); +const addPrefix = (prefix) => (str) => `${prefix}-${str}`; + +// Functional Pipe Operator Implementation +const pipe = (...fns) => (initialValue) => + fns.reduce((acc, currentFn) => currentFn(acc), initialValue); + +const generateSlug = pipe( + trim, + toLowerCase, + replaceSpaces, + addPrefix('article') +); + +console.log(generateSlug(' Mastering Modern JavaScript 2026! ')); +// Output: "article-mastering-modern-javascript-2026!" + +``` + +--- + +## 10. Multi-Threading with Web Workers & Transferable Objects + +Because JavaScript runs on a single thread, cpu-intensive tasks can block the UI thread. **Web Workers** run scripts on background background OS threads. + +### Implementation + +```javascript +// main.js - Main Thread +const worker = new Worker('worker.js'); + +// Allocate 64MB ArrayBuffer +const allocationSize = 8 * 1024 * 1024; +const memoryBuffer = new ArrayBuffer(allocationSize * 8); + +// Transfer ownership to worker without memory copy overhead +worker.postMessage({ dataBuffer: memoryBuffer }, [memoryBuffer]); + +console.log('Main memory size after transfer:', memoryBuffer.byteLength); // 0 (Detached) + +worker.onmessage = (event) => { + console.log('Worker task complete!', event.data); + worker.terminate(); +}; +``` + +## Summary Checklist for JS Developers + +* [x] **Event Loop:** Clear microtasks before yielding to macrotasks or UI renders. +* [x] **Memory Management:** Clean up event listeners using `AbortController` signals. +* [x] **V8 Performance:** Write monomorphic calls to maintain V8 Inline Caches. +* [x] **Modern Features:** Use explicit resource management (`using`) and non-mutating array operations (`toSorted`, `with`). + +*Enjoyed this article? Share it or follow me on [GitHub](https://github.com/ajay-dhangar) and [LinkedIn](https://www.linkedin.com/in/ajay-dhangar/).* \ No newline at end of file diff --git a/blog/tags.yml b/blog/tags.yml deleted file mode 100644 index bfaa778..0000000 --- a/blog/tags.yml +++ /dev/null @@ -1,19 +0,0 @@ -facebook: - label: Facebook - permalink: /facebook - description: Facebook tag description - -hello: - label: Hello - permalink: /hello - description: Hello tag description - -docusaurus: - label: Docusaurus - permalink: /docusaurus - description: Docusaurus tag description - -hola: - label: Hola - permalink: /hola - description: Hola tag description diff --git a/docs/01-getting-started/_category_.json b/docs/01-getting-started/_category_.json new file mode 100644 index 0000000..7130ae1 --- /dev/null +++ b/docs/01-getting-started/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Getting Started", + "position": 1, + "link": { + "type": "generated-index", + "title": "Getting Started with JavaScript", + "description": "Welcome to JavaScript Mastery! Learn the core setup, runtime environments, browser developer tools, and foundational concepts to start building with JavaScript.", + "slug": "/" + } +} \ No newline at end of file diff --git a/docs/01-getting-started/environment-setup.md b/docs/01-getting-started/environment-setup.md new file mode 100644 index 0000000..27a69e5 --- /dev/null +++ b/docs/01-getting-started/environment-setup.md @@ -0,0 +1,168 @@ +--- +id: environment-setup +title: "Setting Up Your JavaScript Environment" +sidebar_label: Environment Setup +sidebar_position: 2 +description: "Configure Node.js, package managers, browser dev tools, and VS Code for modern JavaScript development." +tags: [setup, nodejs, vscode, devtools, workflow] +keywords: [setup, nodejs, vscode, devtools, workflow] +--- + +import CodeBlock from "@theme/CodeBlock"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +To write, debug, and optimize modern JavaScript efficiently, you need a robust local setup. This guide covers configuring **Node.js**, **browser Developer Tools**, and **Visual Studio Code**. + +## The Essential Toolchain + +A modern JavaScript workflow relies on three core pillars: + +| Tool | Purpose | Primary Use Case | +| :--- | :--- | :--- | +| **Node.js & npm** | JavaScript Runtime & Package Manager | Executing JS outside browsers, managing dependencies | +| **Browser DevTools** | Inspection & Debugging | DOM inspection, performance profiling, network logs | +| **VS Code** | Code Editor & IDE | Autocompletion, linting, formatting, integrated terminal | + +## 1. Installing Node.js & Package Managers + +**Node.js** allows you to execute JavaScript on your local machine outside of a web browser. + +:::tip LTS vs. Current +Always download the **LTS (Long Term Support)** version for maximum stability and ecosystem compatibility. +::: + +### Step 1: Verify or Install Node.js + +Check if Node.js is already installed on your system by running these commands in your terminal: + +```bash title="Terminal" +node -v +npm -v +``` + +If not installed, choose your operating system setup below: + + + + + +```bash +brew install node +``` + + + + + +```powershell +winget install OpenJS.NodeJS.LTS +``` + + + + + +```bash +curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - +sudo apt-get install -y nodejs +``` + + + + +## 2. Configuring Visual Studio Code + +**Visual Studio Code (VS Code)** is the industry-standard IDE for web development. + +### Recommended Extensions + +Install these essential extensions to automate formatting and detect syntax bugs instantly: + +* **Prettier - Code formatter** (`esbenp.prettier-vscode`): Enforces consistent code formatting. +* **ESLint** (`dbaeumer.vscode-eslint`): Identifies logic errors and bad patterns. +* **Live Server** (`ritwickdey.liveserver`): Launches a local development server with live reload. +* **JavaScript (ES6) code snippets** (`xabikos.javascriptsnippets`): Provides modern syntax shortcuts. + +### Recommended VS Code Workspace Settings + +Create or update `.vscode/settings.json` in your project root to auto-format files on save: + +```json title=".vscode/settings.json" +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "javascript.suggest.completeFunctionCalls": true, + "files.autoSave": "afterDelay" +} + +``` + +## 3. Mastering Browser Developer Tools + +Every modern browser comes with built-in Developer Tools (DevTools). Access them using: + +* **Windows/Linux**: `F12` or `Ctrl + Shift + I` +* **macOS**: `Cmd + Option + I` + +### Core DevTools Tabs Explained + +```text +DevTools Engine +├── Console -> Live REPL for logging and instant JS execution +├── Elements -> Live DOM modification and CSS inspection +├── Sources -> Breakpoint debugging and callstack inspection +├── Network -> Monitoring HTTP requests, APIs, and load times +└── Application -> Managing LocalStorage, SessionStorage, and Cookies + +``` + +## Knowledge Check: Your First Local JS Script + +Let's test your local setup by creating and running a script using Node.js. + +### Step 1: Create a workspace directory + +```bash title="Terminal" +mkdir js-practice +cd js-practice +``` + +### Step 2: Create a test script (`app.js`) + +```javascript title="app.js" +const systemInfo = { + environment: "Node.js", + status: "Active", + timestamp: new Date().toISOString(), +}; + +console.log("System Check Successful:"); +console.table(systemInfo); + +``` + +### Step 3: Run the script + +```bash title="Terminal" +node app.js +``` + +```text + System Check Successful: +┌─────────────┬──────────────────────────┐ +│ (index) │ Values │ +├─────────────┼──────────────────────────┤ +│ environment │ 'Node.js' │ +│ status │ 'Active' │ +│ timestamp │'2026-09-04T03:02:54.920Z'│ +└─────────────┴──────────────────────────┘ + +``` + +:::success Environment Ready! +Your local environment is fully configured. Proceed to **Phase 02: JavaScript Fundamentals** to master variables, types, and scope! +::: \ No newline at end of file diff --git a/docs/01-getting-started/introduction.md b/docs/01-getting-started/introduction.md new file mode 100644 index 0000000..7092bdd --- /dev/null +++ b/docs/01-getting-started/introduction.md @@ -0,0 +1,124 @@ +--- +id: introduction +title: "JavaScript Mastery: The Complete Guide" +sidebar_label: Introduction +sidebar_position: 1 +description: "Master JavaScript from fundamentals to advanced architecture with interactive examples." +tags: [javascript, tutorial, web-development, getting-started] +keywords: [javascript, tutorial, web-development, getting-started] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/getting-started/01-javascript-tutorial.js"; + +> **"JavaScript is the language of the web. Master the language, master the web."** + +Welcome to **JavaScript Mastery**. Over the last decade, JavaScript has evolved from a simple client-side scripting tool into a dominant, full-stack programming ecosystem powering web apps, servers, mobile platforms, and desktop software. + +This documentation is engineered to transform your understanding from surface-level syntax to **deep architectural mastery** through interactive execution and mental-model building. + +## Why This Guide? + +Traditional docs often focus solely on syntax syntax syntax without explaining *why* things work or *how* the runtime executes your code under the hood. + +:::tip What Makes This Guide Different? +* **Interactive Code Playgrounds**: Don't just read code—execute, edit, and experiment in real-time. +* **Modern ES6+ Standards**: Focus on current industry best practices, modern APIs, and clean code patterns. +* **Engine Level Mental Models**: Build deep intuition for complex concepts like **Closures**, the **Event Loop**, **Scope Chains**, and **Prototypes**. +::: + +## Your Learning Roadmap + +We have structured your learning journey into four distinct, progressive phases: + +| Phase | Level | Core Focus | Key Topics Covered | +| :--- | :--- | :--- | :--- | +| **01. Foundations** | Beginner | The Core Building Blocks | Variables, Data Types, Operators, Control Flow | +| **02. Logic & Data** | Intermediate | Code Architecture | Functions, Arrays, Objects, Prototypes, Immutability | +| **03. The Browser** | Intermediate | Web & User Interaction | DOM Tree, Event Delegation, Web APIs, Local Storage | +| **04. Advanced Core** | Advanced | Asynchronous & Engine Mechanics | Async/Await, Promises, Closures, Modules, Event Loop | + +## Start Your Engines + +Let's test your environment and verify your interactive editor integration right now. Modify the code block below and click **Run** to execute your code live. + + + {firstExample} + + +## Who Is This For? + +This guide is designed for developers at any stage looking to solidify their technical expertise: + +* **Aspiring Developers**: Build a rock-solid, production-ready career foundation. +* **Self-Taught Engineers**: Fill in deep knowledge gaps about JavaScript runtime internals. +* **Developers Switching Languages**: Quickly map C++, Java, or Python paradigms to JS concepts. + +## Prerequisites + +To get the most out of this documentation site, you only need: + +1. **A Modern Web Browser**: Google Chrome, Mozilla Firefox, or Brave. +2. **Basic HTML/CSS Knowledge**: Helpful for understanding DOM interactions. +3. **A Curiosity Mindset**: Ready to test hypotheses and learn through hands-on experimentation. + +## Knowledge Check: The Identity Challenge + +Let's do your first quick hands-on check! + +### Exercise Requirements: +1. Declare a constant variable `developerName` and assign your name as a string. +2. Declare a variable `experienceLevel` and assign a string or number. +3. Log both variables to the console using a template literal. + +
+👉 Click to View Solution + +```javascript title="solution.js" +// 1. Declare constants for immutable values +const developerName = "JavaScript Master"; + +// 2. Declare let for values that can change +let experienceLevel = 1; + +// 3. Output using template literals +console.log(`Hello, I am ${developerName} with Level ${experienceLevel} expertise!`); + +``` + +
+ +:::success Next Steps +Ready to dive deeper? Proceed to the next page to configure your local development environment and developer tools! +::: + + +``` +docs/ +├── 03-deep-dive-core/ +│ ├── _category_.json +│ ├── closures-and-lexical-scope.md +│ ├── prototype-and-inheritance.md +│ ├── execution-context-and-callstack.md +│ └── this-keyword-explained.md +├── 04-asynchronous-javascript/ +│ ├── _category_.json +│ ├── event-loop-and-task-queue.md +│ ├── promises-and-async-await.md +│ └── fetch-api-and-ajax.md +├── 05-dom-and-browser-apis/ +│ ├── _category_.json +│ ├── dom-manipulation.md +│ ├── event-handling-and-delegation.md +│ └── web-storage-and-cookies.md +├── 06-modern-es6-plus/ +│ ├── _category_.json +│ ├── destructuring-and-rest-spread.md +│ ├── modules-import-export.md +│ └── iterators-and-generators.md +└── 07-design-patterns-and-best-practices/ + ├── _category_.json + ├── design-patterns.md + └── clean-code-and-performance.md +``` \ No newline at end of file diff --git a/docs/02-javascript-fundamentals/_category_.json b/docs/02-javascript-fundamentals/_category_.json new file mode 100644 index 0000000..8b2d591 --- /dev/null +++ b/docs/02-javascript-fundamentals/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "JavaScript Fundamentals", + "position": 2, + "link": { + "type": "generated-index", + "title": "JavaScript Fundamentals", + "description": "Master core language constructs including variable scoping, primitive and complex data types, type coercion, function declarations, and control flow mechanics.", + "slug": "/category/javascript-fundamentals" + } +} \ No newline at end of file diff --git a/docs/02-javascript-fundamentals/data-types-and-coercion.md b/docs/02-javascript-fundamentals/data-types-and-coercion.md new file mode 100644 index 0000000..2d8483c --- /dev/null +++ b/docs/02-javascript-fundamentals/data-types-and-coercion.md @@ -0,0 +1,155 @@ +--- +id: data-types-and-coercion +title: "Data Types & Type Coercion" +sidebar_label: Data Types & Coercion +sidebar_position: 2 +description: "Master primitive and reference data types in JavaScript, memory allocation, explicit type conversion, and implicit type coercion mechanics." +tags: [javascript, fundamentals, datatypes, coercion, equality] +keywords: [javascript, datatypes, coercion, equality, type conversion, type coercion] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/javascript-fundamentals/coercion-lab.js"; + +JavaScript is a **dynamically typed** language. This means variables do not have fixed types; instead, the values assigned to them do. Understanding how JavaScript classifies types and converts them internally prevents subtle runtime bugs. + +## The 8 JavaScript Data Types + +JavaScript categorizes values into two main memory structures: **Primitives** and **Reference Types (Objects)**. + +```text +JavaScript Data Types +├── 🧊 Primitives (Immutable, Stored by Value on Stack) +│ ├── String +│ ├── Number +│ ├── BigInt +│ ├── Boolean +│ ├── Undefined +│ ├── Null +│ └── Symbol +└── 📦 Reference Types (Mutable, Stored by Reference on Heap) + └── Object (Arrays, Functions, Dates, Objects) + +``` + +| Type | Description | Example | +| --- | --- | --- | +| **String** | Textual data enclosed in quotes | `"Hello World"`, `'JS'` | +| **Number** | Double-precision 64-bit float | `42`, `3.14`, `NaN`, `Infinity` | +| **BigInt** | Arbitrary-precision integers | `9007199254740991n` | +| **Boolean** | Logical entity | `true`, `false` | +| **Undefined** | Variable declared but not assigned | `let x;` | +| **Null** | Intentional absence of value | `const user = null;` | +| **Symbol** | Unique, immutable identifier | `Symbol("id")` | +| **Object** | Collection of key-value pairs | `{ name: "Alex", age: 25 }` | + +:::warning The `typeof null` Caveat +`typeof null` returns `"object"`. This is a historic bug from the first version of JavaScript and is preserved for backward compatibility. +::: + +## Memory: Primitives vs. Reference Types + +Primitives are copied **by value**, while objects are copied **by reference**. + +```javascript title="memory.js" +// Primitive: Value Copy +let x = 10; +let y = x; // Copy created +y = 20; +console.log(x); // 10 (unmodified) + +// Reference: Pointer Copy +let obj1 = { name: "Alice" }; +let obj2 = obj1; // Copies memory reference +obj2.name = "Bob"; +console.log(obj1.name); // "Bob" (mutated!) +``` + +## Type Conversion vs. Type Coercion + +* **Explicit Conversion**: Intentional conversion performed using built-in constructors (`String()`, `Number()`, `Boolean()`). +* **Implicit Coercion**: Automatic type conversion triggered by operators or binary operations. + +### 1. Truthy vs. Falsy Values + +JavaScript coerces values to `Boolean` in logical contexts (`if`, `while`, logical operators). + +There are exactly **8 Falsy values**: + +* `false` +* `0`, `-0`, `0n` +* `""` (empty string) +* `null` +* `undefined` +* `NaN` + +*Everything else in JavaScript is **Truthy*** (including `{}` and `[]`). + +### 2. The `+` Operator Coercion Rules + +The addition operator handles both numeric addition and string concatenation: + +```javascript +"5" + 2; // "52" (Number coerced to String) +"5" - 2; // 3 (String coerced to Number) +"5" * "2"; // 10 (Both coerced to Numbers) + +``` + +### 3. Loose (`==`) vs. Strict (`===`) Equality + +* **`==` (Loose)**: Coerces types before comparison. +* **`===` (Strict)**: Compares both **value** and **type** without coercion. + +```javascript title="equality.js" +5 == "5"; // true (Coerced) +5 === "5"; // false (Types differ) + +null == undefined; // true +null === undefined; // false + +``` + +## Interactive Playground: Coercion Lab + +Test how JavaScript evaluates implicit type conversions in real time: + + + {firstExample} + + +## Best Practices + +1. **Always use `===**`: Prevent unpredictable behavior caused by implicit coercion during equality checks. +2. **Explicitly convert types**: Use `Number(str)`, `String(val)`, or `Boolean(val)` instead of relying on implicit tricks (`+str` or `!!val`). +3. **Use BigInt for large integers**: Numbers exceed safe integer precision beyond `2^53 - 1` (`Number.MAX_SAFE_INTEGER`). + +## Knowledge Check + +### Exercise Requirements: + +Predict the output of the following coercion operations, then check your answers below. + +1. `true + false` +2. `[] + {}` +3. `typeof NaN` + +```javascript title="solution.js" +// 1. Outputs: 1 +// Booleans are coerced to numbers: true = 1, false = 0 +console.log(true + false); + +// 2. Outputs: "[object Object]" +// Empty array converts to empty string "", object converts to "[object Object]" +console.log([] + {}); + +// 3. Outputs: "number" +// NaN stands for "Not-a-Number", but its data type is officially Number! +console.log(typeof NaN); + +``` + +:::success Next Up +Now that you have mastered data types and coercion, proceed to **Functions and Arrow Functions**! +::: \ No newline at end of file diff --git a/docs/02-javascript-fundamentals/functions-and-arrow-fns.md b/docs/02-javascript-fundamentals/functions-and-arrow-fns.md new file mode 100644 index 0000000..5f6a4c7 --- /dev/null +++ b/docs/02-javascript-fundamentals/functions-and-arrow-fns.md @@ -0,0 +1,171 @@ +--- +id: functions-and-arrow-fns +title: "Functions & Arrow Functions" +sidebar_label: Functions & Arrow Functions +sidebar_position: 3 +description: "Master JavaScript function declarations, function expressions, arrow functions, parameter handling, implicit returns, and lexical 'this' binding." +tags: [javascript, fundamentals, functions, arrow-functions, parameters, execution] +keywords: [javascript, functions, arrow-functions, parameters, execution, lexical-this] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import functionsPlayground from "!!raw-loader!../_scripts/javascript-fundamentals/functions-playground.js"; + +Functions are the primary building blocks of JavaScript applications. They allow you to encapsulate logic, reuse code, and create modular execution blocks. Modern JavaScript provides multiple ways to declare and invoke functions, each with distinct scoping and binding behaviors. + +## Function Declarations vs. Function Expressions + +JavaScript provides two traditional ways to define functions: **Declarations** and **Expressions**. + +```text +Function Definitions +├── Declaration -> Hoisted entirely (can be called before definition) +└── Expression -> Variable assigned (subject to variable hoisting rules) +``` + +| Feature | Function Declaration | Function Expression | +| --- | --- | --- | +| **Syntax** | `function calc() {}` | `const calc = function() {};` | +| **Hoisting** | Hoisted with full body | Variable hoisted (uninitialized/undefined) | +| **Named Option** | Always named | Anonymous or named | +| **Primary Use** | Top-level module utilities | Callbacks, conditional assignments | + +```javascript title="function-types.js" +// Function Declaration (Hoisted) +greet("Alice"); // Works! + +function greet(name) { + return `Hello, ${name}!`; +} + +// Function Expression (Not Hoisted) +// calculateTotal(10, 2); // ReferenceError: Cannot access 'calculateTotal' before initialization + +const calculateTotal = function (price, tax) { + return price + price * tax; +}; + +``` + +## Arrow Functions (ES6+) + +Arrow functions offer a concise syntax for writing function expressions and introduce **lexical `this` binding**. + +### Basic Syntax & Implicit Returns + +When an arrow function consists of a single expression, you can omit the curly braces `{}` and the `return` keyword for an **implicit return**: + +```javascript title="arrow-functions.js" +const multiply = (a, b) => { + return a * b; +}; + +// Concise Arrow Function with Implicit Return +const add = (a, b) => a + b; + +// Implicitly Returning an Object (Wrap in parentheses!) +const createUser = (id, username) => ({ id, username }); + +``` + +## The `this` Keyword: Standard vs. Arrow Functions + +The critical architectural difference between standard functions and arrow functions lies in how they handle `this`. + +* **Standard Functions**: Define `this` **dynamically** based on *how* the function is invoked. +* **Arrow Functions**: Do **not** have their own `this`. They inherit `this` **lexically** from the surrounding outer scope. + +```javascript title="this-binding.js" +const counter = { + count: 0, + + // Standard Function Method + startTimerStandard() { + setTimeout(function () { + // 'this' refers to the global object/undefined in strict mode + console.log("Standard Timer:", this.count); // NaN or Error + }, 100); + }, + + // Arrow Function Method + startTimerArrow() { + setTimeout(() => { + // 'this' lexically inherits from startTimerArrow ('counter' object) + console.log("Arrow Timer:", ++this.count); // 1 + }, 100); + } +}; + +``` + +## Modern Parameter Handling + +### 1. Default Parameters + +Provide fallback values when arguments are missing or `undefined`. + +```javascript title="default-params.js" +function sendNotification(message, priority = "Normal", retryAttempts = 3) { + return `Sending "${message}" [Priority: ${priority}, Retries: ${retryAttempts}]`; +} + +sendNotification("System Update"); +// Output: "Sending \"System Update\" [Priority: Normal, Retries: 3]" + +``` + +### 2. Rest Parameters (`...`) + +Gather an arbitrary number of trailing arguments into a single array. + +```javascript title="rest-params.js" +const sumAll = (...numbers) => { + return numbers.reduce((total, num) => total + num, 0); +}; + +console.log(sumAll(10, 20, 30, 40)); // 100 + +``` + +## Interactive Playground: Functions in Action + +Test implicit returns, rest parameters, and arrow function behaviors live: + + + {functionsPlayground} + + +## Best Practices + +1. **Use Arrow Functions for Callbacks**: Ideal for inline array methods (`map`, `filter`, `reduce`) and event handlers where lexical `this` is desired. +2. **Avoid Arrow Functions for Object Methods**: Don't use arrow functions as primary object methods if you need access to the object's instance via `this`. +3. **Keep Implicit Returns Readable**: If an implicit return expression stretches beyond a single line, wrap it with explicit braces `{ return ... }`. + +## Knowledge Check + +### Exercise Requirements: + +1. Refactor the `processOrders` function to use concise arrow functions and array methods. +2. Calculate the total value of completed orders using rest parameters or array reduction. + +```javascript title="solution.js" +const rawOrders = [ + { id: 1, amount: 100, status: "completed" }, + { id: 2, amount: 50, status: "pending" }, + { id: 3, amount: 200, status: "completed" }, +]; + +// Refactored Arrow Pipeline +const getCompletedTotal = (orders) => + orders + .filter((order) => order.status === "completed") + .reduce((total, order) => total + order.amount, 0); + +console.log("Total Completed:", getCompletedTotal(rawOrders)); // 300 + +``` + +:::success Next Up +Now that you have mastered function declarations and scoping behaviors, proceed to **Operators and Control Flow**! +::: \ No newline at end of file diff --git a/docs/02-javascript-fundamentals/operators-and-control-flow.md b/docs/02-javascript-fundamentals/operators-and-control-flow.md new file mode 100644 index 0000000..7e8deab --- /dev/null +++ b/docs/02-javascript-fundamentals/operators-and-control-flow.md @@ -0,0 +1,170 @@ +--- +id: operators-and-control-flow +title: "Operators & Control Flow" +sidebar_label: Operators & Control Flow +sidebar_position: 4 +description: "Master JavaScript operators, nullish coalescing, optional chaining, conditional branching, and control flow mechanics." +tags: [javascript, fundamentals, operators, control-flow, conditionals, loops] +keywords: [javascript, operators, control-flow, conditionals, loops, nullish coalescing, optional chaining] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/javascript-fundamentals/operators-playground.js"; + +Control flow governs the execution order of statements in your code. By combining comparison operators, modern short-circuiting mechanisms, and branching constructs, you can write resilient and expressive decision logic. + +## Modern Operators & Short-Circuiting + +Modern JavaScript provides powerful operators to streamline conditional checks and handle missing or nullish data safely. + +| Operator | Name | Syntax | Behavior / Rule | +| :--- | :--- | :--- | :--- | +| **`??`** | Nullish Coalescing | `a ?? b` | Returns `b` **only if** `a` is `null` or `undefined` | +| **`?.`** | Optional Chaining | `obj?.prop` | Short-circuits to `undefined` if `obj` is `null` or `undefined` | +| **`&&`** | Logical AND | `a && b` | Returns `a` if falsy; otherwise returns `b` | +| **`\|\|`** | Logical OR | `a \|\| b` | Returns `a` if truthy; otherwise returns `b` | +| **`?:`** | Ternary Operator | `cond ? a : b` | Inline conditional expression | + + +## `||` vs. `??` (Nullish Coalescing) + +The Logical OR operator (`||`) falls back on **any falsy value** (`0`, `""`, `false`, `null`, `undefined`), whereas Nullish Coalescing (`??`) falls back **only on `null` or `undefined`**. + +```javascript title="nullish-coalescing.js" +const userConfig = { + fontSize: 0, + themeColor: "", + showSidebar: false, +}; + +// Logical OR (Overwrites valid zero and empty string values!) +const sizeOR = userConfig.fontSize || 16; // 16 (0 is falsy!) +const themeOR = userConfig.themeColor || "dark"; // "dark" ("" is falsy!) + +// Nullish Coalescing (Preserves valid 0, false, and "") +const sizeNullish = userConfig.fontSize ?? 16; // 0 +const themeNullish = userConfig.themeColor ?? "dark"; // "" + +``` + +## Safe Property Access with Optional Chaining (`?.`) + +Optional chaining prevents runtime `TypeError: Cannot read properties of undefined` exceptions when traversing nested structures: + +```javascript title="optional-chaining.js" +const userResponse = { + profile: { + name: "Alex", + }, +}; + +// Without optional chaining (Verbose & error-prone) +const cityOld = userResponse.profile && userResponse.profile.address && userResponse.profile.address.city; + +// With optional chaining (Clean & safe) +const cityNew = userResponse?.profile?.address?.city; // undefined (No runtime crash!) + +// Optional Method Calls & Array Indexing +const firstTag = userResponse?.tags?.[0]; +const result = userResponse?.getAnalytics?.(); + +``` + +## Branching Mechanics + +### 1. `if / else if / else` + +Standard conditional branching for non-trivial logic. + +### 2. `switch` Statements & Strict Matching + +Useful for multi-branch checks against discrete values. Switches perform **strict equality checks (`===`)**. + +```javascript title="switch-statement.js" +function getRolePermissions(role) { + switch (role) { + case "admin": + case "superadmin": + return ["read", "write", "delete"]; + case "editor": + return ["read", "write"]; + case "viewer": + return ["read"]; + default: + return []; + } +} + +``` + +## Iteration & Looping Mechanics + +JavaScript provides specialized loops designed for different data structures: + +```text +Loops in JavaScript +├── 🔁 for -> Traditional indexed iteration +├── 📦 for...of -> Iterates over values of Iterables (Arrays, Strings, Maps) +└── 🔑 for...in -> Iterates over enumerable keys/properties of Objects + +``` + +```javascript title="looping-mechanics.js" +const frameworkList = ["React", "Vue", "Angular"]; +const metadata = { version: "18.2", author: "Meta" }; + +// 1. for...of (Values) +for (const framework of frameworkList) { + console.log("Framework:", framework); +} + +// 2. for...in (Keys) +for (const key in metadata) { + console.log(`${key}: ${metadata[key]}`); +} + +``` + +:::warning Avoid `for...in` on Arrays +`for...in` iterates over property names (indexes as strings) and inherited prototype keys. Always prefer `for...of` or `.forEach()` for arrays. +::: + +## Interactive Playground: Operators & Control Flow + +Experiment with optional chaining, nullish coalescing, and short-circuiting in real time: + + + {firstExample} + + +## Best Practices + +1. **Prefer `??` over `||` for defaults**: Protect numeric zeros, empty strings, and booleans from being unintentionally overridden. +2. **Chain safely, but don't over-use**: Use `?.` when property existence is genuinely uncertain; avoid using it everywhere to obscure design flaws. +3. **Keep branches clean**: Replace complex, nested `if...else` statements with early `return` guards or lookup maps. + +## Knowledge Check + +### Exercise Requirements: + +1. Safely extract the `zipCode` property from `customerProfile` without throwing an error if `address` is missing. +2. Fall back to `"00000"` if `zipCode` is `null` or `undefined`. + +```javascript title="solution.js" +const customerProfile = { + id: 42, + name: "Jordan", + // address property is missing +}; + +// Combine optional chaining with nullish coalescing +const zipCode = customerProfile?.address?.zipCode ?? "00000"; + +console.log("Zip Code:", zipCode); // Output: "00000" + +``` + +:::success Phase 02 Complete! +Congratulations! You have mastered **JavaScript Fundamentals**. Proceed to **Phase 03: Deep Dive Core** to master closures, prototypes, and engine mechanics! +::: \ No newline at end of file diff --git a/docs/02-javascript-fundamentals/variables-and-scope.md b/docs/02-javascript-fundamentals/variables-and-scope.md new file mode 100644 index 0000000..a362761 --- /dev/null +++ b/docs/02-javascript-fundamentals/variables-and-scope.md @@ -0,0 +1,127 @@ +--- +id: variables-and-scope +title: "Variables, Declarations, and Scope Mechanics" +sidebar_label: Variables & Scope +sidebar_position: 1 +description: "Master variable declarations with var, let, and const, along with lexical scoping, block scope, and hoisting in JavaScript." +tags: [javascript, fundamentals, variables, scope, hoisting] +keywords: [javascript, variables, scope, hoisting, let, const, var] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/javascript-fundamentals/global-scope.js"; +import blockScopeExample from "!!raw-loader!../_scripts/javascript-fundamentals/block-scope-example.js"; +import scopePlayground from "!!raw-loader!../_scripts/javascript-fundamentals/scope-playground.js"; +import solution from "!!raw-loader!../_scripts/javascript-fundamentals/solution.js"; +import varHoisting from "!!raw-loader!../_scripts/javascript-fundamentals/var-hoisting.js"; +import temporalDeadZone from "!!raw-loader!../_scripts/javascript-fundamentals/temporal-dead-zone.js"; + +In JavaScript, variables store data values, but how and where you declare them dictates their lifecycle, accessibility, and mutability. Understanding variable declarations and scoping mechanics is essential to writing clean, bug-free code. + +## Declaration Types: `var` vs `let` vs `const` + +JavaScript offers three keywords for variable declaration: `var` (ES5), `let` (ES6), and `const` (ES6). + +| Feature | `var` | `let` | `const` | +| :--- | :--- | :--- | :--- | +| **Scope Level** | Function / Global | Block Scope `{}` | Block Scope `{}` | +| **Re-declaration** | Allowed | Syntax Error | Syntax Error | +| **Re-assignment** | Allowed | Allowed | TypeError | +| **Hoisting Behavior** | Initialized as `undefined` | Uninitialized (Temporal Dead Zone) | Uninitialized (Temporal Dead Zone) | +| **Global Object Property** | Yes (`window.x`) | No | No | + +## Scope Types Explained + +Scope determines the visibility and accessibility of variables in different parts of your code. + +```text +Scope Hierarchy +├── Global Scope -> Accessible anywhere in the execution context +├── Function Scope -> Bound inside function boundary (var, let, const) +└── Block Scope -> Bound inside block curly braces {} (let, const only) + +``` + +### 1. Global Scope + +Variables declared outside any function or block belong to the global scope. + + + {firstExample} + + +:::note + +When you run the above code, the output is undefined because the variable `globalAppTitle` is declared in the global scope and is accessible inside the function `printTitle()`. + +So, when we call `printTitle()`, it logs the value of `globalAppTitle` to the console. + +**For example:** + +```js {4,6} +const globalAppTitle = "JavaScript Mastery"; + +function printTitle() { + console.log(globalAppTitle); // Accessible here +} +printTitle(); // Logs: "JavaScript Mastery" +``` +::: + +### 2. Block Scope (`let` / `const`) + +Variables declared with `let` and `const` inside `{}` cannot be accessed outside that block. + + + {blockScopeExample} + + +## Hoisting & The Temporal Dead Zone (TDZ) + +**Hoisting** is JavaScript's default behavior of moving declarations to the top of their containing scope during the compilation phase prior to code execution. + +### `var` Hoisting + +Declarations are hoisted and initialized with `undefined`. + + + {varHoisting} + + +### `let` and `const` Hoisting (The TDZ) + +`let` and `const` variables are hoisted, but remain **uninitialized**. The time between entering scope and variable declaration is called the **Temporal Dead Zone (TDZ)**. + + + {temporalDeadZone} + + +## Interactive Playground: Scope Exploration + +Try editing the script below to observe how block scope and variable re-assignments behave live: + + + {scopePlayground} + + +## Best Practices + +1. **Default to `const**`: Protect variables from unintended re-assignments. +2. **Use `let` for reassignment**: Use only when values must mutate (e.g., loop counters, accumulators). +3. **Avoid `var**`: Prevent scope-leakage issues and silent hoisting bugs in modern applications. + +## Knowledge Check + +### Exercise Requirements: + +1. Fix the variable declarations below so no variables leak outside the `if` block. +2. Ensure `API_KEY` cannot be accidentally reassigned later in execution. + + + {solution} + + +:::success Next Up +Now that you understand variable lifetimes and scoping, proceed to **Data Types and Type Coercion**! +::: \ No newline at end of file diff --git a/docs/02-shadowing.mdx b/docs/02-shadowing.mdx deleted file mode 100644 index bfcf64b..0000000 --- a/docs/02-shadowing.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_label: Variable Shadowing -title: Understanding Variable Shadowing in JavaScript -description: "Learn how variable shadowing works in JavaScript, the difference between inner and outer scope, and how to avoid illegal shadowing." -keywords: [javascript shadowing, lexical scope, illegal shadowing, var vs let, javascript tutorial] ---- - -import JSEditor from "@site/src/components/js-live-code-editor"; -import firstExample from "!!raw-loader!./_scripts/02-shadow-01.js"; -import secondExample from "!!raw-loader!./_scripts/02-shadow-02.js"; -import thirdExample from "!!raw-loader!./_scripts/02-shadow-03.js"; - -**Variable Shadowing** occurs when a variable declared within a specific scope (like a function or a block) has the same name as a variable in an outer scope. - -When this happens, the inner variable "shadows" the outer one, making the outer variable inaccessible within that specific inner block. - -## How Shadowing Works - -In the example below, notice how the `city` inside the function is independent of the `city` defined at the top level. - - - {firstExample} - - -> **What's happening?** > The `city` parameter on **Line 3** shadows the `city` variable on **Line 1**. Any changes made to `city` inside the function (Line 4) stay inside the function's "bubble." - -## The Rules of Shadowing - -While shadowing is a common pattern, JavaScript has strict rules about how different declaration types (`var`, `let`, `const`) interact across scopes. - -### 1. Illegal Shadowing - -You cannot shadow a `let` or `const` variable using `var` within the same block or a nested block. This is because `var` is function-scoped and tries to "hoist" itself to the top, which conflicts with the block-scoped `let`. - - - {secondExample} - - -*The `var` at line 4 is trying to **'cross the boundary'** of the `let` declaration, which results in a SyntaxError.* - -### 2. Valid Shadowing (Function Boundaries) - -Shadowing becomes valid again if there is a **function boundary** separating the declarations. Since functions create a completely new execution context, the conflict is resolved. - - - {thirdExample} - - -## Best Practices - -* **Avoid Name Collision:** While shadowing is technically allowed, using the same name for different variables can lead to "Silent Bugs" that are hard to debug. -* **Be Specific:** Instead of shadowing `data`, use more descriptive names like `userData` and `filteredData`. \ No newline at end of file diff --git a/docs/03-deep-dive-core/_category_.json b/docs/03-deep-dive-core/_category_.json new file mode 100644 index 0000000..ed70023 --- /dev/null +++ b/docs/03-deep-dive-core/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Deep Dive Core", + "position": 3, + "link": { + "type": "generated-index", + "title": "Deep Dive into Core JavaScript Mechanics", + "description": "Master advanced JavaScript runtime internals including lexical environments, closures, prototype inheritance chains, execution contexts, call stacks, and dynamic 'this' binding.", + "slug": "/category/deep-dive-core" + } +} \ No newline at end of file diff --git a/docs/03-deep-dive-core/closures-and-lexical-scope.md b/docs/03-deep-dive-core/closures-and-lexical-scope.md new file mode 100644 index 0000000..d69f6f0 --- /dev/null +++ b/docs/03-deep-dive-core/closures-and-lexical-scope.md @@ -0,0 +1,183 @@ +--- +id: closures-and-lexical-scope +title: "Closures & Lexical Scope Mechanics" +sidebar_label: Closures & Lexical Scope +sidebar_position: 1 +description: "Master lexical environments, scope chains, closures, state encapsulation, memoization, and garbage collection mechanics in JavaScript." +tags: [javascript, advanced, closures, scope, memory, execution-context] +keywords: [javascript, advanced, closures, scope, memory, execution-context] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/deep-dive-core/closure-playground.js"; + +Closures are one of the most fundamental and powerful features in JavaScript. They enable functions to retain access to variables from their enclosing lexical scope even after that parent scope has finished executing. + +## Lexical Scope & Scope Chains + +JavaScript uses **Lexical Scoping** (also called static scoping). This means variable resolution is determined by the physical placement of functions and blocks within the source code at compile time, not where they are called at runtime. + +```text +Scope Chain Resolution Hierarchy +┌─────────────────────────────────────────┐ +│ Global Lexical Environment │ +│ └─ Outer Function Lexical Environment │ +│ └─ Inner Function Lexical Environment (Active Search Starts Here) +└─────────────────────────────────────────┘ + +``` + +When an inner function attempts to access a variable, the engine searches: + +1. Its own local Lexical Environment. +2. The outer (parent) Lexical Environment. +3. Up the prototype/scope chain until it reaches the Global Scope. +4. If unfound, throws a `ReferenceError`. + +## What is a Closure? + +> **Definition**: A **closure** is the combination of a function bundled together (enclosed) with references to its surrounding state (its **Lexical Environment**). + +Whenever a function is created in JavaScript, a closure is created. Inner functions automatically maintain a reference to their outer environment via an internal property called `[[Environment]]`. + +```javascript title="closure-example.js" +function createCounter(initialValue = 0) { + // Free variable retained by closure + let count = initialValue; + + return { + increment() { + count++; + return count; + }, + decrement() { + count--; + return count; + }, + getValue() { + return count; + } + }; +} + +const counter = createCounter(10); +console.log(counter.increment()); // 11 +console.log(counter.increment()); // 12 +console.log(counter.getValue()); // 12 +// Note: 'count' cannot be accessed directly or modified outside these methods! + +``` + +## Practical Enterprise Patterns Using Closures + +### 1. Data Encapsulation & Private State + +JavaScript didn't historically have native private class fields (`#field`). Closures were—and still are—used to hide implementation details and protect state from unwanted external mutation. + +### 2. Function Currying & Partial Application + +Closures allow us to lock in arguments across multiple function invocations: + +```javascript title="currying-example.js" +const multiply = (a) => (b) => a * b; + +const double = multiply(2); +const triple = multiply(3); + +console.log(double(5)); // 10 +console.log(triple(5)); // 15 + +``` + +### 3. Memoization (Caching Expensive Computations) + +Closures hold persistent cache maps across function execution lifecycle runs: + +```javascript title="memoization-example.js" +function memoize(fn) { + const cache = new Map(); + + return function (...args) { + const key = JSON.stringify(args); + if (cache.has(key)) { + return cache.get(key); // Return cached result + } + const result = fn(...args); + cache.set(key, result); + return result; + }; +} + +``` + +## Common Pitfalls & Garbage Collection + +While closures are powerful, holding long-lived references to outer scopes can cause unintended memory retention if not managed properly. + +### The Classic `var` Loop Issue + +Historically, using `var` inside `for` loops resulted in shared closure references across iterations: + +```javascript title="var-loop-closure.js" +// Problematic (var is function-scoped) +for (var i = 1; i <= 3; i++) { + setTimeout(() => console.log(`Var Loop: ${i}`), 100); +} +// Output after 100ms: 4, 4, 4 + +// Fixed with Block Scope (let creates a fresh binding per iteration) +for (let j = 1; j <= 3; j++) { + setTimeout(() => console.log(`Let Loop: ${j}`), 100); +} +// Output after 100ms: 1, 2, 3 + +``` + +## Interactive Playground: Closures in Action + +Experiment with private counters, memoization, and scope retention in real time: + + + {firstExample} + + + +## Best Practices + +1. **Protect Sensitive State**: Use closures when you need strict read/write boundaries for object properties or service handlers. +2. **Clean Up Unused Handlers**: Remove event listeners or interval timers that retain references to heavy DOM elements or arrays to avoid memory leaks. +3. **Prefer `let` in Iterations**: Avoid wrapping loop bodies in Immediately Invoked Function Expressions (IIFEs) just to capture variables—use block-scoped `let` instead. + +## Knowledge Check + +### Exercise Requirements: + +Write a function `createLimiter(fn, maxCalls)` that returns a wrapper function. The wrapped function should execute `fn` only up to `maxCalls` times, returning `"Limit reached"` on any subsequent calls. + +```javascript title="solution.js" +function createLimiter(fn, maxCalls) { + let callCount = 0; + + return function (...args) { + if (callCount < maxCalls) { + callCount++; + return fn(...args); + } + return "Limit reached"; + }; +} + +// Verification +const sayHello = () => "Hello World!"; +const limitedHello = createLimiter(sayHello, 2); + +console.log(limitedHello()); // "Hello World!" +console.log(limitedHello()); // "Hello World!" +console.log(limitedHello()); // "Limit reached" + +``` + +:::success Next Up +Now that you have mastered lexical scope and closure mechanics, proceed to **Prototypes and Inheritance**! +::: \ No newline at end of file diff --git a/docs/03-deep-dive-core/execution-context-and-callstack.md b/docs/03-deep-dive-core/execution-context-and-callstack.md new file mode 100644 index 0000000..c2ba0b0 --- /dev/null +++ b/docs/03-deep-dive-core/execution-context-and-callstack.md @@ -0,0 +1,150 @@ +--- +id: execution-context-and-callstack +title: "Execution Context & The Call Stack" +sidebar_label: Execution Context & Call Stack +sidebar_position: 3 +description: "Master the JavaScript execution engine, creation and execution phases, global and function execution contexts, call stack mechanics, and stack overflow errors." +tags: [javascript, advanced, execution-context, call-stack, memory, engine] +keywords: [javascript, advanced, execution-context, call-stack, memory, engine] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/deep-dive-core/execution-context-playground.js"; + +To write high-performance JavaScript and debug complex async code, you need to understand how the JavaScript engine parses and executes your scripts under the hood. Everything in JavaScript happens inside an **Execution Context**, managed strictly by the **Call Stack**. + +## What is an Execution Context? + +An **Execution Context (EC)** is an abstract environment created by the engine to evaluate and execute JavaScript code. It contains the environment record (variables, functions, arguments), lexical scope links, and the binding of `this`. + +```text +Types of Execution Contexts +├── Global Execution Context (GEC) -> Created by default before any code runs (1 per thread) +├── Function Execution Context (FEC)-> Created whenever a function is invoked +└── Eval Execution Context -> Created when code executes inside eval() (rarely used) + +``` + +## The Two-Phase Execution Lifecycle + +Every execution context goes through two distinct phases before your code actually runs line-by-line: + +```text +Execution Context Lifecycle +┌──────────────────────────────────────────────────────────┐ +│ 1. Creation Phase (Memory Allocation) │ +│ ├── Create Global/Outer Environment Reference │ +│ ├── Allocate memory for variables (hoisted as undefined)│ +│ ├── Store function declarations in heap memory │ +│ └── Bind 'this' keyword │ +├──────────────────────────────────────────────────────────┤ +│ 2. Execution Phase (Code Evaluation) │ +│ ├── Assign values to variables line-by-line │ +│ └── Execute function calls & evaluate expressions │ +└──────────────────────────────────────────────────────────┘ + +``` + +### Creation Phase vs. Execution Phase Example + +```javascript title="execution-context-example.js" +var title = "JavaScript Mastery"; +function getDetails(level) { + var prefix = "Level"; + return `${prefix} ${level}: ${title}`; +} +var result = getDetails("Advanced"); + +``` + +During the **Creation Phase**: + +1. `title` is allocated in memory and set to `undefined`. +2. `getDetails` function declaration is stored in memory in its entirety. +3. `result` is allocated in memory and set to `undefined`. + +During the **Execution Phase**: + +1. `title` is assigned `"JavaScript Mastery"`. +2. `getDetails("Advanced")` is called, creating a new **Function Execution Context**. +3. `result` receives the returned string. + +## The Call Stack (Execution Stack) + +JavaScript is **single-threaded**—it has one call stack and can only perform one task at a time. The **Call Stack** is a LIFO (Last In, First Out) data structure that keeps track of active execution contexts. + +```text +Call Stack Execution Visualizer +┌───────────────────────┐ +│ FEC: multiply() │ <- Currently Executing (Pushed on top) +├───────────────────────┤ +│ FEC: calculateTotal() │ +├───────────────────────┤ +│ Global Context (GEC) │ <- Bottom of Stack (Always active until tab closes) +└───────────────────────┘ + +``` + +When a function is called, its FEC is **pushed** onto the stack. When the function returns a value or reaches its end, its FEC is **popped** off the stack, returning execution to the underlying context. + +## Stack Overflow + +When recursive functions fail to define a proper base case or recurse too deeply, the call stack exceeds its maximum allocation limits, throwing a `RangeError: Maximum call stack size exceeded`. + +```javascript title="stack-overflow-example.js" +// Stack Overflow Danger! +function recursiveCrash() { + return recursiveCrash(); // Infinite recursion without base condition +} + +// recursiveCrash(); // Un-commenting will freeze or overflow the call stack + +``` + +## Interactive Playground: Tracing Execution Contexts + +Run the script below and observe how functions nest during invocation: + + + {firstExample} + + +## Best Practices + +1. **Avoid Infinite Recursion**: Always establish clear, reachable base conditions in recursive algorithms. +2. **Minimize Deep Call Stacks**: Deeply nested function calls increase stack depth and memory usage; refactor heavy recursion into iterative loops where necessary. +3. **Understand Hoisting Through Phases**: Remember that function declarations are hoisted with their complete implementation, while variable declarations with `var` are hoisted as `undefined`. + +## Knowledge Check + +### Exercise Requirements: + +1. Trace the stack push/pop order for the following function calls: `main()` -> `parseData()` -> `validate()`. +2. What will be logged to the console before `a` is initialized in the execution phase? + +```javascript title="knowledge-check.js" +console.log(a); +var a = 42; + +``` + +```javascript title="solution.js" +// 1. Stack Order: +// - PUSH GEC +// - PUSH FEC: main() +// - PUSH FEC: parseData() +// - PUSH FEC: validate() +// - POP FEC: validate() +// - POP FEC: parseData() +// - POP FEC: main() + +// 2. Output for console.log(a): +// Output: undefined +// Reason: During the creation phase, 'a' is allocated memory and initialized to undefined. + +``` + +:::success Next Up +Now that you understand execution contexts and call stack mechanics, proceed to **The `this` Keyword Explained**! +::: \ No newline at end of file diff --git a/docs/03-deep-dive-core/prototype-and-inheritance.md b/docs/03-deep-dive-core/prototype-and-inheritance.md new file mode 100644 index 0000000..776b0bc --- /dev/null +++ b/docs/03-deep-dive-core/prototype-and-inheritance.md @@ -0,0 +1,161 @@ +--- +id: prototype-and-inheritance +title: "Prototypes & Inheritance Mechanics" +sidebar_label: Prototypes & Inheritance +sidebar_position: 2 +description: "Master JavaScript prototype chains, object linkage, constructor functions, ES6 classes, and prototypal inheritance patterns." +tags: [javascript, advanced, prototype, inheritance, OOP, classes] +keywords: [javascript, advanced, prototype, inheritance, OOP, classes] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/deep-dive-core/prototype-playground.js"; + +Unlike traditional class-based object-oriented languages like Java or C++, JavaScript uses **Prototypal Inheritance**. Every JavaScript object possesses an internal link to another object called its **Prototype**, forming a chain used for property and method resolution. + +## The Prototype Chain + +When you attempt to access a property or method on an object, the JavaScript engine follows a strict lookup procedure: + +```text +Prototype Resolution Chain +┌──────────────────────────────────────────────┐ +│ myObject │ +│ └─ [[Prototype]] -> DeveloperPrototype │ +│ └─ [[Prototype]] -> Object.prototype │ +│ └─ [[Prototype]] -> null │ +└──────────────────────────────────────────────┘ + +``` + +1. Checks if the property exists directly on `myObject` (an **own property**). +2. If missing, traverses up the internal `[[Prototype]]` link. +3. Continues climbing until it finds the property or reaches `Object.prototype.[[Prototype]]`, which is `null`. +4. Returns `undefined` if the property is unfound anywhere along the chain. + +## `prototype` Property vs. `__proto__` + +A common source of confusion in JavaScript is the distinction between `Function.prototype` and `Object.__proto__`. + +| Entity | Description | Where It Exists | +| --- | --- | --- | +| **`prototype`** | Blueprint object assigned to instances created via `new`. | Exists **only** on Functions / Classes | +| **`__proto__`** | Historic getter/setter exposing an object's internal `[[Prototype]]`. | Exists on all Objects | +| **`Object.getPrototypeOf()`** | Modern standard method to access an object's prototype. | Built-in static method | + +```javascript title="prototype-vs-__proto__.js" +function User(name) { + this.name = name; +} + +User.prototype.sayHello = function () { + return `Hello, I'm ${this.name}`; +}; + +const alex = new User("Alex"); + +console.log(alex.__proto__ === User.prototype); // true +console.log(Object.getPrototypeOf(alex) === User.prototype); // true + +``` + +## Prototypal vs. Class-Based Syntax + +ES6 introduced the `class` keyword. However, JavaScript classes are primarily **syntactic sugar** over the existing prototypal system—under the hood, functions and prototypes still power everything. + +### Prototypal Delegation Pattern + +```javascript title="prototypal-delegation.js" +const animalActions = { + eat() { + return `${this.name} is eating.`; + } +}; + +// Create object linked directly to animalActions +const dog = Object.create(animalActions); +dog.name = "Rex"; + +console.log(dog.eat()); // "Rex is eating." + +``` + +### Modern ES6 Class Syntax + +```javascript title="es6-class-syntax.js" +class Animal { + constructor(name) { + this.name = name; + } + + eat() { + return `${this.name} is eating.`; + } +} + +class Dog extends Animal { + constructor(name, breed) { + super(name); // Call parent constructor + this.breed = breed; + } + + bark() { + return `${this.name} barks loudly!`; + } +} + +const rex = new Dog("Rex", "German Shepherd"); +console.log(rex.eat()); // "Rex is eating." (Inherited from Animal) +console.log(rex.bark()); // "Rex barks loudly!" + +``` + +## Interactive Playground: Prototypal Chain Lookup + +Inspect prototype linkage, property shadows, and method overrides in real time: + + + {firstExample} + + +## Best Practices + +1. **Use ES6 Class Syntax for Readability**: Prefer `class` and `extends` for clean OOP structures, but remember it uses prototypes underneath. +2. **Avoid Modifying Native Prototypes**: Do not extend built-in objects like `Array.prototype` or `Object.prototype` (monkey patching), as it causes collisions with third-party libraries. +3. **Use `Object.getPrototypeOf()**`: Avoid using the legacy `__proto__` accessor in production code; use standard methods like `Object.getPrototypeOf()` and `Object.setPrototypeOf()`. + +## Knowledge Check + +### Exercise Requirements: + +1. Implement a constructor function or class `Shape` that accepts `color`. +2. Extend `Shape` with a `Rectangle` subclass that accepts `color`, `width`, and `height`, and includes a method `getArea()`. + +```javascript title="solution.js" +class Shape { + constructor(color) { + this.color = color; + } +} + +class Rectangle extends Shape { + constructor(color, width, height) { + super(color); + this.width = width; + this.height = height; + } + + getArea() { + return this.width * this.height; + } +} + +const rect = new Rectangle("blue", 10, 5); +console.log(`Color: ${rect.color}, Area: ${rect.getArea()}`); // Color: blue, Area: 50 + +``` + +:::success Next Up +Now that you have mastered prototype delegation and class mechanics, proceed to **Execution Context and Call Stack**! +::: \ No newline at end of file diff --git a/docs/03-deep-dive-core/this-keyword-explained.md b/docs/03-deep-dive-core/this-keyword-explained.md new file mode 100644 index 0000000..c7eb281 --- /dev/null +++ b/docs/03-deep-dive-core/this-keyword-explained.md @@ -0,0 +1,203 @@ +--- +id: this-keyword-explained +title: "The 'this' Keyword Explained" +sidebar_label: The 'this' Keyword +sidebar_position: 4 +description: "Master JavaScript's dynamic 'this' binding rules: implicit, explicit, new, default global binding, and lexical arrow function behavior." +tags: [javascript, advanced, this, execution-context, binding, OOP] +keywords: [javascript, advanced, this, execution-context, binding, OOP] +--- + +import JSEditor from "@site/src/components/js-live-code-editor"; +import CodeBlock from "@theme/CodeBlock"; +import firstExample from "!!raw-loader!../_scripts/deep-dive-core/this-binding-playground.js"; + +In JavaScript, `this` is a keyword whose value is determined dynamically at **call time** (how and where a function is invoked), rather than where the function is defined. The only exception is arrow functions, which use **lexical binding**. + +## The 5 Rules of `this` Binding + +To determine what `this` refers to in any function call, evaluate invocation against these 5 precedence rules: + +```text +Binding Precedence Hierarchy (Highest to Lowest) +┌─────────────────────────────────────────┐ +│ 1. 'new' Binding │ +│ 2. Explicit Binding (call, apply, bind) │ +│ 3. Implicit Binding (Context Object) │ +│ 4. Default / Global Binding │ +│ 5. Lexical Binding (Arrow Functions) │ +└─────────────────────────────────────────┘ + +``` + +## 1. Implicit Binding (Object Context) + +When a function is invoked as a method of an object (using dot notation), `this` points to the object preceding the dot: + +```javascript title="implicit-binding.js" +const user = { + name: "Alex", + greet() { + return `Hello, my name is ${this.name}`; + } +}; + +console.log(user.greet()); // "Hello, my name is Alex" + +``` + +:::warning Implicit Binding Loss +Assigning a method to a separate variable strips its object context: + +```javascript title="implicit-binding-loss.js" +const unboundGreet = user.greet; +console.log(unboundGreet()); // "Hello, my name is undefined" (or throws in strict mode) + +``` + +::: + +## 2. Explicit Binding (`call`, `apply`, `bind`) + +You can explicitly force a function to execute with a specific `this` context using JavaScript's built-in prototype methods: + +| Method | Invocation | Arguments Format | Execution | +| --- | --- | --- | --- | +| **`call()`** | Direct | Comma-separated (`obj, arg1, arg2`) | Executes immediately | +| **`apply()`** | Direct | Array of arguments (`obj, [arg1, arg2]`) | Executes immediately | +| **`bind()`** | Indirect | Comma-separated (`obj, arg1, arg2`) | Returns a **new bound function** | + +```javascript +function updateProfile(role, location) { + this.role = role; + this.location = location; + return `${this.name} is a ${this.role} in ${this.location}`; +} + +const person = { name: "Jordan" }; + +// 1. call +console.log(updateProfile.call(person, "Lead Architect", "Berlin")); + +// 2. apply +console.log(updateProfile.apply(person, ["Principal Engineer", "Remote"])); + +// 3. bind +const boundFn = updateProfile.bind(person, "DevOps Manager", "Tokyo"); +console.log(boundFn()); + +``` + +## 3. `new` Binding (Constructor Invocation) + +When a function is called with the `new` keyword: + +1. A brand new empty object `{}` is created. +2. The object is linked to the function's prototype (`[[Prototype]]`). +3. `this` inside the function is bound to that newly created object. +4. The function implicitly returns the object (unless a different object is returned explicitly). + +```javascript title="new-binding.js" +function Developer(name, language) { + this.name = name; + this.language = language; +} + +const dev = new Developer("Sam", "JavaScript"); +console.log(dev.name); // "Sam" + +``` + +## 4. Default / Global Binding + +When a standalone function is called without any context object: + +* In **Non-Strict Mode**: `this` defaults to the global object (`window` in browsers, `global` in Node.js). +* In **Strict Mode (`"use strict"`)**: `this` evaluates to `undefined`. + +```javascript title="default-binding.js" +function checkContext() { + "use strict"; + return this; +} + +console.log(checkContext()); // undefined + +``` + +## 5. Lexical `this` (Arrow Functions) + +Arrow functions do **not** have their own `this`. They capture the `this` value from their enclosing execution scope at the time they are created: + +```javascript title="arrow-function-this.js" +const company = { + name: "CodeHarborHub", + getBrand: function () { + return `Company: ${this.name}`; + }, + getBrandArrow: () => { + return `Company: ${this.name}`; // 'this' is lexically bound to the outer scope (global) + } +}; +const timer = { + seconds: 0, + start() { + // Arrow function lexically captures 'this' from start() method context + setInterval(() => { + this.seconds++; + console.log(`Elapsed: ${this.seconds}s`); + }, 1000); + } +}; + +``` + +## Interactive Playground: `this` Binding Lab + +Test explicit binding, loss of implicit context, and arrow function behaviors live: + + + {firstExample} + + +## Best Practices + +1. **Use Arrow Functions for Callbacks**: Preserve outer `this` inside event listeners, timers, and array methods without needing `const self = this` or explicit `.bind(this)`. +2. **Avoid Arrow Functions for Object Methods**: Defining object methods with arrow functions will bind `this` to the outer global scope instead of the object itself. +3. **Always Enable Strict Mode**: Prevent accidental global variable mutations caused by default `this` binding in standalone functions. + +## Knowledge Check + +### Exercise Requirements: + +Fix the bugs in the object below so `getDetails` correctly logs the user's details without throwing `TypeError` or logging `undefined`. + +```javascript title="knowledge-check.js" +const userProfile = { + username: "CodeNinja", + skills: ["JS", "TS", "React"], + getDetails: () => { + return `${this.username} knows ${this.skills.join(", ")}`; + } +}; + +``` + +```javascript title="solution.js" +const userProfile = { + username: "CodeNinja", + skills: ["JS", "TS", "React"], + // Replace arrow function with standard method definition + getDetails() { + return `${this.username} knows ${this.skills.join(", ")}`; + } +}; + +console.log(userProfile.getDetails()); +// Output: "CodeNinja knows JS, TS, React" + +``` + +:::success Phase 03 Complete! +Congratulations! You have completed **Phase 03: Deep Dive Core**. Proceed to **Phase 04: Asynchronous JavaScript** to master the event loop, promises, and async/await! +::: \ No newline at end of file diff --git a/docs/03-varible-declaration.mdx b/docs/03-varible-declaration.mdx deleted file mode 100644 index a3e358a..0000000 --- a/docs/03-varible-declaration.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -sidebar_label: "Var, Let & Const" -title: Variable Declarations -description: "A deep dive into JavaScript variable scopes (Global, Function, Block), Hoisting mechanisms, and the modern differences between var, let, and const." -keywords: [javascript variables, hoisting, var let const differences, functional scope, block scope, js execution context] ---- - -import JSEditor from "@site/src/components/js-live-code-editor"; -import firstExample from "!!raw-loader!./_scripts/03-variable-declaration-01.js"; -import secondExample from "!!raw-loader!./_scripts/03-variable-declaration-02.js"; -import thirdExample from "!!raw-loader!./_scripts/03-variable-declaration-03.js"; -import fourthExample from "!!raw-loader!./_scripts/03-variable-declaration-04.js"; -import fifthExample from "!!raw-loader!./_scripts/03-variable-declaration-05.js"; - -Understanding how JavaScript handles variables is the foundation of mastering the language. It’s not just about syntax; it’s about how the **JS Engine** prepares your code before a single line is executed. - -## 1. The Legacy: `var` - -Before ES6, `var` was the only way to declare variables. It behaves differently than modern keywords because it ignores **block scope** (like `if` statements or `for` loops). - -### Scope: Global vs. Function - -* **Global Scope:** When declared outside a function, it attaches to the `window` object (in browsers). -* **Function Scope:** When declared inside a `function`, it is trapped there and cannot be accessed from outside. - - - {firstExample} - - -### Re-declaration & Updates - -One of the "quirks" of `var` is that it allows you to re-declare the same variable name without an error. In large codebases, this often leads to accidental bugs. - - - - {secondExample} - - -:::tip Technical Insight -A repeated `var` declaration in the same scope is effectively a **do-nothing operation**. The JS engine sees the first one and ignores subsequent declarations of the same name. -::: - -## 2. Hoisting: The "Pre-Process" Phase - -Hoisting is a mental metaphor for how the JS Engine sets up the program. Think of it as a two-pass system: -1. **Pass 1 (Compile/Setup):** Find all declarations and "hoist" them to the top. -2. **Pass 2 (Execution):** Run the code line-by-line. - -### How `var` Hoists -When `var` is hoisted, it is automatically initialized with `undefined`. - -```js title="The Hoisting Transformation" -// What you write: -console.log(age); // undefined -var age = 25; - -// How JS interprets it: -var age; // 1. Declaration hoisted & initialized to undefined -console.log(age); // 2. Logs undefined -age = 25; // 3. Assignment happens here -``` - -### Function Hoisting Priority - -Functions are the "VIPs" of hoisting. They are moved to the top **before** variable declarations. - - -{fourthExample} - - -## 3. The Modern Way: `let` & `const` - -While `var` is function-scoped, `let` and `const` are **block-scoped** `{ }`. They also exist in a "Temporal Dead Zone" (TDZ) which prevents them from being used before they are declared—making your code much safer. - -| Feature | `var` | `let` | `const` | -| :--- | :--- | :--- | :--- | -| **Scope** | Function | Block | Block | -| **Hoisting** | Yes (undefined) | Yes (TDZ) | Yes (TDZ) | -| **Re-declare** | Yes | No | No | -| **Re-assign** | Yes | Yes | No | - -## Interactive Challenges - -Test your understanding of the execution context with these common interview scenarios. - - -{fifthExample} - - -:::info Deep Dive -For a deeper understanding of these mechanics, I highly recommend checking out: - -- [Var, Let, and Const – What's the Difference?](https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/) -- [Scope and Closures (You Don't Know JS)](https://github.com/getify/You-Dont-Know-JS) -::: \ No newline at end of file diff --git a/docs/04-asynchronous-javascript/_category_.json b/docs/04-asynchronous-javascript/_category_.json new file mode 100644 index 0000000..a3f1615 --- /dev/null +++ b/docs/04-asynchronous-javascript/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Asynchronous JavaScript", + "position": 4, + "link": { + "type": "generated-index", + "title": "Asynchronous JavaScript & Engine Concurrency", + "description": "Master non-blocking asynchronous execution in JavaScript, including the Event Loop, Microtask vs. Macrotask queues, Promises, Async/Await architecture, and the Fetch API.", + "slug": "/category/asynchronous-javascript" + } +} \ No newline at end of file diff --git a/docs/04-asynchronous-javascript/event-loop-and-task-queue.md b/docs/04-asynchronous-javascript/event-loop-and-task-queue.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/04-asynchronous-javascript/fetch-api-and-ajax.md b/docs/04-asynchronous-javascript/fetch-api-and-ajax.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/04-asynchronous-javascript/promises-and-async-await.md b/docs/04-asynchronous-javascript/promises-and-async-await.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/05-dom-and-browser-apis/_category_.json b/docs/05-dom-and-browser-apis/_category_.json new file mode 100644 index 0000000..e881fd9 --- /dev/null +++ b/docs/05-dom-and-browser-apis/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "DOM & Browser APIs", + "position": 5, + "link": { + "type": "generated-index", + "title": "DOM Manipulation & Web Browser APIs", + "description": "Master DOM traversal, high-performance element manipulation, event handling and delegation, storage mechanics, and modern browser Web APIs.", + "slug": "/category/dom-and-browser-apis" + } +} \ No newline at end of file diff --git a/docs/05-dom-and-browser-apis/dom-manipulation.md b/docs/05-dom-and-browser-apis/dom-manipulation.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/05-dom-and-browser-apis/event-handling-and-delegation.md b/docs/05-dom-and-browser-apis/event-handling-and-delegation.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/05-dom-and-browser-apis/web-storage-and-cookies.md b/docs/05-dom-and-browser-apis/web-storage-and-cookies.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/06-modern-es6-plus/_category_.json b/docs/06-modern-es6-plus/_category_.json new file mode 100644 index 0000000..deb2553 --- /dev/null +++ b/docs/06-modern-es6-plus/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Modern ES6+", + "position": 6, + "link": { + "type": "generated-index", + "title": "Modern ES6+ Features & Syntax Enhancements", + "description": "Master contemporary JavaScript features including destructuring, rest & spread operations, ES modules (import/export), iterators, and generators.", + "slug": "/category/modern-es6-plus" + } +} \ No newline at end of file diff --git a/docs/06-modern-es6-plus/destructuring-and-rest-spread.md b/docs/06-modern-es6-plus/destructuring-and-rest-spread.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/06-modern-es6-plus/iterators-and-generators.md b/docs/06-modern-es6-plus/iterators-and-generators.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/06-modern-es6-plus/modules-import-export.md b/docs/06-modern-es6-plus/modules-import-export.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/07-design-patterns-and-best-practices/_category_.json b/docs/07-design-patterns-and-best-practices/_category_.json new file mode 100644 index 0000000..79cadc3 --- /dev/null +++ b/docs/07-design-patterns-and-best-practices/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Design Patterns & Best Practices", + "position": 7, + "link": { + "type": "generated-index", + "title": "Design Patterns & Production Best Practices", + "description": "Master essential software design patterns in JavaScript, clean coding principles, performance optimization techniques, memory management, and enterprise architecture guidelines.", + "slug": "/category/design-patterns-and-best-practices" + } +} \ No newline at end of file diff --git a/docs/07-design-patterns-and-best-practices/clean-code-and-performance.md b/docs/07-design-patterns-and-best-practices/clean-code-and-performance.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/07-design-patterns-and-best-practices/design-patterns.md b/docs/07-design-patterns-and-best-practices/design-patterns.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/_scripts/01-this-arrow-function-01.js b/docs/_scripts/01-this-arrow-function-01.js deleted file mode 100644 index 3a042cd..0000000 --- a/docs/_scripts/01-this-arrow-function-01.js +++ /dev/null @@ -1,30 +0,0 @@ -const person1 = { - Name: "Ajay", - sayName: () => { - console.log(`Hello, my name is ${this.Name}`); - }, -}; - -const person2 = {}; -person2.Name = "Ajay"; -person2.sayName = () => { - console.log(`Hello, my name is ${this.Name}`); -}; - -// pre-es6 -var self = this; // captures this -const person3 = {}; -person3.Name = "Ajay"; -person3.sayName = function () { - console.log(`Hello, my name is ${self.Name}`); -}; - -function sayName() { - console.log(`Hello, my name is ${this.Name}`); -} - -var Name = "[[Global Name]]"; -person1.sayName(); // Hello, my name is [[Global Name]] -person2.sayName(); // Hello, my name is [[Global Name]] -person3.sayName(); // Hello, my name is [[Global Name]] -sayName(); // Hello, my name is [[Global Name]] diff --git a/docs/_scripts/01-this-arrow-function-02.js b/docs/_scripts/01-this-arrow-function-02.js deleted file mode 100644 index 5b50c1b..0000000 --- a/docs/_scripts/01-this-arrow-function-02.js +++ /dev/null @@ -1,16 +0,0 @@ -function Person(name) { - this.Name = name; - this.sayName = () => { - console.log(`Hello, my name is ${this.Name}`); - }; - // pre-es6 - var self = this; - this.sayNameFunc = function () { - console.log(`Hello, my name is ${self.Name}`); - }; -} - -const person = new Person("Ajay"); -// polyfill: these two ways of defining functions have the same effect -person.sayName(); -person.sayNameFunc(); \ No newline at end of file diff --git a/docs/_scripts/01-this-arrow-function-03.js b/docs/_scripts/01-this-arrow-function-03.js deleted file mode 100644 index adc1009..0000000 --- a/docs/_scripts/01-this-arrow-function-03.js +++ /dev/null @@ -1,19 +0,0 @@ -function Person(name) { - this.Name = name; - this.sayName = () => { - console.log(`Hello, my name is ${this.Name}`); - }; -} - -const person1 = new Person("Ajay"); -const person2 = new Person("dan-dan"); - -person2.sayName(); -// [[implict binding]] cannot change `this` -// p1's sayName still points at person1 -person2.sayName = person1.sayName; -person2.sayName(); - -// [[explict binding]] cannot change `this` -console.log(person1); -person2.sayName.call(person1); \ No newline at end of file diff --git a/docs/_scripts/01-this-class-01.js b/docs/_scripts/01-this-class-01.js deleted file mode 100644 index fafa51d..0000000 --- a/docs/_scripts/01-this-class-01.js +++ /dev/null @@ -1,24 +0,0 @@ -class Person { - constructor(name) { - this.Name = name; - } - sayNameMethod() { - console.log(`Hello, my name is ${this.Name}`); - } - sayNamePropFunc = function () { - console.log(`Hello, my name is ${this.Name}`); - }; - sayNamePropArrow = () => { - console.log(`Hello, my name is ${this.Name}`); - }; -} - -const person1 = new Person("Ajay"); - -person1.sayNameMethod(); -person1.sayNamePropFunc(); -person1.sayNamePropArrow(); - -person1.sayNameMethod.call({ Name: "[[called by call(...)]]" }); // work -person1.sayNamePropFunc.call({ Name: "[[called by call(...)]]" }); // work -person1.sayNamePropArrow.call({ Name: "[[called by call(...)]]" }); // does not work \ No newline at end of file diff --git a/docs/_scripts/01-this-explicit-binding-01.js b/docs/_scripts/01-this-explicit-binding-01.js deleted file mode 100644 index 927bf82..0000000 --- a/docs/_scripts/01-this-explicit-binding-01.js +++ /dev/null @@ -1,16 +0,0 @@ -function sayNameFunc() { - console.log(`Hello, my name is ${this.Name}.`); -} - -const person = { - Name: "Ajay", -}; - -const sayNameBinded = function () { - sayNameFunc.call(person); -}; - -sayNameBinded(); -sayNameBinded.call({ Name: "name passed by the line 14 call" }); - -sayNameFunc.call({ Name: "fake name" }); \ No newline at end of file diff --git a/docs/_scripts/01-this-first.js b/docs/_scripts/01-this-first.js deleted file mode 100644 index 1b8ba52..0000000 --- a/docs/_scripts/01-this-first.js +++ /dev/null @@ -1,27 +0,0 @@ -function baz() { - // call-stack is: `baz` - // so, our call-site is in the global scope - console.log("baz"); - bar(); // <-- call-site for `bar` -} - -function bar() { - // call-stack is: `baz` -> `bar` - // so, our call-site is in `baz` - - console.log("bar"); - foo(); // <-- call-site for `foo` -} - -function foo() { - // call-stack is: `baz` -> `bar` -> `foo` - // so, our call-site is in `bar` - - debugger; // remove this line to view the console output - - console.log("foo"); -} - -baz(); // <-- call-site for `baz` - -// Retrieved from https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch2.md \ No newline at end of file diff --git a/docs/_scripts/01-this-implicit-binding-01.js b/docs/_scripts/01-this-implicit-binding-01.js deleted file mode 100644 index 5144b8e..0000000 --- a/docs/_scripts/01-this-implicit-binding-01.js +++ /dev/null @@ -1,10 +0,0 @@ -function sayNameFunc() { - console.log(`Hello, my name is ${this.name}`); -} - -const person = { - name: "Ajay", - sayName: sayNameFunc, -}; - -person.sayName(); // Hello, my name is Ajay \ No newline at end of file diff --git a/docs/_scripts/01-this-implicit-binding-02.js b/docs/_scripts/01-this-implicit-binding-02.js deleted file mode 100644 index a29e52b..0000000 --- a/docs/_scripts/01-this-implicit-binding-02.js +++ /dev/null @@ -1,16 +0,0 @@ -function sayNameFunc() { - console.log(`Hello, my name is ${this.name}`); -} - -const person = { - name: "Ajay", - sayName: sayNameFunc, -}; - -const home = { - name: "QuanZhou", - owner: person, -}; - -person.sayName(); // Hello, my name is Ajay -home.owner.sayName(); // Hello, my name is Ajay \ No newline at end of file diff --git a/docs/_scripts/01-this-new-binding-01.js b/docs/_scripts/01-this-new-binding-01.js deleted file mode 100644 index 3960b3b..0000000 --- a/docs/_scripts/01-this-new-binding-01.js +++ /dev/null @@ -1,6 +0,0 @@ -function Person(name) { - this.Name = name; -} - -const person = new Person("Ajay"); -console.log(person.Name); \ No newline at end of file diff --git a/docs/_scripts/01-this-order-01.js b/docs/_scripts/01-this-order-01.js deleted file mode 100644 index 44c591f..0000000 --- a/docs/_scripts/01-this-order-01.js +++ /dev/null @@ -1,13 +0,0 @@ -function Person(name) { - this.Name = name; -} - -const p1 = {}; -const PersonAnother = Person.bind(p1); -PersonAnother("dan-dan"); - -console.log(p1.Name); - -const p2 = new PersonAnother("Ajay"); -console.log(p1.Name); -console.log(p2.Name); \ No newline at end of file diff --git a/docs/_scripts/02-shadow-01.js b/docs/_scripts/02-shadow-01.js deleted file mode 100644 index fed1268..0000000 --- a/docs/_scripts/02-shadow-01.js +++ /dev/null @@ -1,12 +0,0 @@ -const city = "Quanzhou"; - -function printCity(city) { - city = city.toUpperCase(); - console.log(city); -} - -printCity("Shenzhen"); - -printCity(city); - -console.log(city); \ No newline at end of file diff --git a/docs/_scripts/02-shadow-02.js b/docs/_scripts/02-shadow-02.js deleted file mode 100644 index 209ff4d..0000000 --- a/docs/_scripts/02-shadow-02.js +++ /dev/null @@ -1,14 +0,0 @@ -function sayCity() { - { - let city = "Quanzhou"; - { - var city = "Shenzhen"; - console.log(city); - } - console.log(city); - } - // var is function-scoped, so city would be accessible here - // if it didn't throw a SyntaxError - console.log(city); -} -sayCity() \ No newline at end of file diff --git a/docs/_scripts/02-shadow-03.js b/docs/_scripts/02-shadow-03.js deleted file mode 100644 index dc957cd..0000000 --- a/docs/_scripts/02-shadow-03.js +++ /dev/null @@ -1,13 +0,0 @@ -function getTodos() { - { - let userId = 1; - - (() => { - var userId = 7; - console.log(userId); - })(); - console.log(userId); - } -} - -getTodos(); \ No newline at end of file diff --git a/docs/_scripts/03-variable-declaration-01.js b/docs/_scripts/03-variable-declaration-01.js deleted file mode 100644 index 234e5a2..0000000 --- a/docs/_scripts/03-variable-declaration-01.js +++ /dev/null @@ -1,6 +0,0 @@ -function sayAge() { - var age = 666; - console.log(age); -} -sayAge(); -console.log(age); \ No newline at end of file diff --git a/docs/_scripts/03-variable-declaration-02.js b/docs/_scripts/03-variable-declaration-02.js deleted file mode 100644 index f2de5e1..0000000 --- a/docs/_scripts/03-variable-declaration-02.js +++ /dev/null @@ -1,7 +0,0 @@ -var age = 10; -var age = 20; // re-declare 'age' -console.log(age); - -// update 'age' -age = 30; -console.log(age); \ No newline at end of file diff --git a/docs/_scripts/03-variable-declaration-03.js b/docs/_scripts/03-variable-declaration-03.js deleted file mode 100644 index 33b21fe..0000000 --- a/docs/_scripts/03-variable-declaration-03.js +++ /dev/null @@ -1,6 +0,0 @@ -var studentName = "Frank"; -console.log(studentName); -// Frank - -var studentName; -console.log(studentName); // ??? \ No newline at end of file diff --git a/docs/_scripts/03-variable-declaration-04.js b/docs/_scripts/03-variable-declaration-04.js deleted file mode 100644 index 2437139..0000000 --- a/docs/_scripts/03-variable-declaration-04.js +++ /dev/null @@ -1,13 +0,0 @@ -console.log(a); -if (a) { - var a = 1; - console.log(a); -} - -function a() { - console.log(this); -} - -console.log(a); - -a(); \ No newline at end of file diff --git a/docs/_scripts/03-variable-declaration-05.js b/docs/_scripts/03-variable-declaration-05.js deleted file mode 100644 index 5867d55..0000000 --- a/docs/_scripts/03-variable-declaration-05.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -var b = 2; -if (true) { - let a = 2; - var b = 3; - var c = 4; - const d = 5; -} - -// console.log(a); ReferenceError: a is not defined -console.log(b); -console.log(c); -console.log(d); -var d = 6; \ No newline at end of file diff --git a/docs/_scripts/deep-dive-core/closure-playground.js b/docs/_scripts/deep-dive-core/closure-playground.js new file mode 100644 index 0000000..b817cd6 --- /dev/null +++ b/docs/_scripts/deep-dive-core/closure-playground.js @@ -0,0 +1,24 @@ +const createBankAccount = (initialBalance = 0) => { + let balance = initialBalance; // Private variable retained by closure + return { + deposit(amount) { + if (amount <= 0) return "Invalid amount"; + balance += amount; + return `Deposited: $${amount} | New Balance: $${balance}`; + }, + withdraw(amount) { + if (amount > balance) return "Insufficient funds!"; + balance -= amount; + return `Withdrew: $${amount} | New Balance: $${balance}`; + }, + getBalance() { + return `Current Balance: $${balance}`; + }, + }; +}; + +const myAccount = createBankAccount(500); +console.log(myAccount.deposit(200)); +console.log(myAccount.withdraw(150)); +console.log(myAccount.getBalance()); +console.log("Direct Balance Access:", myAccount.balance); // undefined! diff --git a/docs/_scripts/deep-dive-core/execution-context-playground.js b/docs/_scripts/deep-dive-core/execution-context-playground.js new file mode 100644 index 0000000..51bd6fe --- /dev/null +++ b/docs/_scripts/deep-dive-core/execution-context-playground.js @@ -0,0 +1,18 @@ +function firstTask() { + console.log("1. Inside firstTask()"); + secondTask(); +} + +function secondTask() { + console.log("2. Inside secondTask()"); + thirdTask(); + console.log("3. Exiting secondTask()"); +} + +function thirdTask() { + console.log(" -> Inside thirdTask() [Top of Stack]"); +} + +console.log("--- Starting Execution ---"); +firstTask(); +console.log("--- Execution Completed ---"); diff --git a/docs/_scripts/deep-dive-core/prototype-playground.js b/docs/_scripts/deep-dive-core/prototype-playground.js new file mode 100644 index 0000000..4b7c822 --- /dev/null +++ b/docs/_scripts/deep-dive-core/prototype-playground.js @@ -0,0 +1,18 @@ +// 1. Create a prototype object +const vehiclePrototype = { + startEngine() { + return `${this.type} engine started!`; + } +}; + +// 2. Link Object via Object.create() +const myCar = Object.create(vehiclePrototype); +myCar.type = "Sports Sedan"; // Property Shadowing + +// 3. Inspect Linkage +console.log(myCar.startEngine()); +console.log("Has Own Property 'type':", myCar.hasOwnProperty("type")); +console.log("Has Own Property 'startEngine':", myCar.hasOwnProperty("startEngine")); + +// 4. Verify Prototype Chain +console.log("Is prototype linked:", Object.getPrototypeOf(myCar) === vehiclePrototype); \ No newline at end of file diff --git a/docs/_scripts/deep-dive-core/this-binding-playground.js b/docs/_scripts/deep-dive-core/this-binding-playground.js new file mode 100644 index 0000000..11a215b --- /dev/null +++ b/docs/_scripts/deep-dive-core/this-binding-playground.js @@ -0,0 +1,16 @@ +// 1. Implicit Binding +const company = { + name: "CodeHarborHub", + getBrand() { + return `Company: ${this.name}`; + } +}; +console.log("Implicit Call:", company.getBrand()); + +// 2. Explicit Override +const externalCompany = { brand: "CodeHarborHub" }; +console.log("Explicit Override:", company.getBrand.call(externalCompany)); + +// 3. Hard Binding +const fixedBrand = company.getBrand.bind(externalCompany); +console.log("Bound Output:", fixedBrand()); \ No newline at end of file diff --git a/docs/_scripts/01-javascript-tutorial.js b/docs/_scripts/getting-started/01-javascript-tutorial.js similarity index 100% rename from docs/_scripts/01-javascript-tutorial.js rename to docs/_scripts/getting-started/01-javascript-tutorial.js diff --git a/docs/_scripts/javascript-fundamentals/block-scope-example.js b/docs/_scripts/javascript-fundamentals/block-scope-example.js new file mode 100644 index 0000000..498aaf7 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/block-scope-example.js @@ -0,0 +1,7 @@ +if (true) { + var functionScopedVar = "I leak outside!"; + let blockScopedLet = "I am trapped inside!"; +} + +console.log(functionScopedVar); // "I leak outside!" +console.log(blockScopedLet); // ReferenceError: blockScopedLet is not defined diff --git a/docs/_scripts/javascript-fundamentals/coercion-lab.js b/docs/_scripts/javascript-fundamentals/coercion-lab.js new file mode 100644 index 0000000..aa1335a --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/coercion-lab.js @@ -0,0 +1,14 @@ +// 1. Implicit String Coercion +console.log("Result 1:", "5" + 3); + +// 2. Implicit Numeric Coercion +console.log("Result 2:", "10" - 5); + +// 3. Falsy vs Truthy Evaluations +console.log("Empty Array Truthy Test:", Boolean([])); +console.log("Empty Object Truthy Test:", Boolean({})); + +// 4. Loose Equality Quirks +console.log("0 == false:", 0 == false); +console.log("'' == false:", '' == false); +console.log("0 === false:", 0 === false); \ No newline at end of file diff --git a/docs/_scripts/javascript-fundamentals/functions-playground.js b/docs/_scripts/javascript-fundamentals/functions-playground.js new file mode 100644 index 0000000..5561e26 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/functions-playground.js @@ -0,0 +1,13 @@ +// 1. Implicit Return +const square = (n) => n * n; + +// 2. Rest Parameters +const calculateAverage = (...scores) => { +const sum = scores.reduce((acc, score) => acc + score, 0); +return (sum / scores.length).toFixed(1); +}; +console.log("Average Score:", calculateAverage(85, 90, 78, 92)); + +// 3. Arrow Function Object Return +const makePoint = (x, y) => ({ x, y, timestamp: Date.now() }); +console.log("Point Object:", makePoint(10, 25)); \ No newline at end of file diff --git a/docs/_scripts/javascript-fundamentals/global-scope.js b/docs/_scripts/javascript-fundamentals/global-scope.js new file mode 100644 index 0000000..93a08d0 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/global-scope.js @@ -0,0 +1,5 @@ +const globalAppTitle = "JavaScript Mastery"; + +function printTitle() { + console.log(globalAppTitle); // Accessible here +} \ No newline at end of file diff --git a/docs/_scripts/javascript-fundamentals/operators-playground.js b/docs/_scripts/javascript-fundamentals/operators-playground.js new file mode 100644 index 0000000..79a1f84 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/operators-playground.js @@ -0,0 +1,20 @@ +// 1. Nullish Coalescing +const userSettings = { + theme: null, + notifications: undefined, +}; + +// 2. Deep Optional Chaining +const apiData = { +status: 200, +data: { +users: [{ id: 101, details: { email: "alex@example.com" } }] +} +}; + +const secondUserEmail = apiData?.data?.users?.[1]?.details?.email ?? "Email Not Found"; +console.log("Safe Fetch Output:", secondUserEmail); + +// 3. Short-circuit execution +const isLogged = true; +isLogged && console.log("User session verified!"); \ No newline at end of file diff --git a/docs/_scripts/javascript-fundamentals/scope-playground.js b/docs/_scripts/javascript-fundamentals/scope-playground.js new file mode 100644 index 0000000..758051f --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/scope-playground.js @@ -0,0 +1,15 @@ +const maxLimit = 500; +// maxLimit = 600; // Un-comment to see TypeError! + +// 2. Block Scope Test +function runScopeTest() { +if (true) { +var varMessage = "Accessible outside block"; +let letMessage = "Hidden inside block"; +} +console.log(varMessage); +// console.log(letMessage); // Un-comment to see ReferenceError +} + +runScopeTest(); +console.log(`Points: ${points}, Max: ${maxLimit}`); \ No newline at end of file diff --git a/docs/_scripts/javascript-fundamentals/solution.js b/docs/_scripts/javascript-fundamentals/solution.js new file mode 100644 index 0000000..5a474b7 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/solution.js @@ -0,0 +1,6 @@ +const API_KEY = "SECRET_12345"; // Read-only + +if (true) { + let sessionToken = "ABC-XYZ"; // Safely block-scoped + console.log(`Session: ${sessionToken}`); +} diff --git a/docs/_scripts/javascript-fundamentals/temporal-dead-zone.js b/docs/_scripts/javascript-fundamentals/temporal-dead-zone.js new file mode 100644 index 0000000..4d74b01 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/temporal-dead-zone.js @@ -0,0 +1,4 @@ +// Entering block scope -> TDZ begins +console.log(score); // ReferenceError: Cannot access 'score' before initialization + +let score = 100; // TDZ ends diff --git a/docs/_scripts/javascript-fundamentals/var-hoisting.js b/docs/_scripts/javascript-fundamentals/var-hoisting.js new file mode 100644 index 0000000..6d494f6 --- /dev/null +++ b/docs/_scripts/javascript-fundamentals/var-hoisting.js @@ -0,0 +1,2 @@ +console.log(user); // Output: undefined (no error) +var user = "Alex"; \ No newline at end of file diff --git a/docs/index.mdx b/docs/index.mdx deleted file mode 100644 index 0808670..0000000 --- a/docs/index.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: docs -title: "JavaScript Mastery: The Complete Guide" -sidebar_label: Introduction -sidebar_position: 1 -slug: / -description: "Master JavaScript from fundamentals to advanced architecture with interactive examples." -tags: [javascript, tutorial, web-development] ---- - -import JSEditor from "@site/src/components/js-live-code-editor"; - -import CodeBlock from "@theme/CodeBlock"; -import firstExample from "!!raw-loader!./_scripts/01-javascript-tutorial.js"; - -> **"JavaScript is the language of the web. Master the language, master the web."** - -JavaScript has evolved from a simple scripting tool to a powerhouse capable of building full-scale enterprise applications, mobile apps, and server-side systems. This guide is designed to take you from **zero to architectural hero** through hands-on execution. - -## Why This Guide? - -Unlike traditional documentation, **JavaScript Mastery** focuses on deep understanding over rote memorization. - -:::tip What makes this different? -- **Live Execution**: Don't just read code—run it and break it in our integrated editors. -- **Modern Standards**: We focus on ES6+ and current industry best practices. -- **Mental Models**: Learn how the engine works under the hood (Closures, Event Loop, Hoisting). -::: - -## Your Learning Path - -We have structured this journey into four distinct phases: - - -| Phase | Focus | Key Topics | -| :--- | :--- | :--- | -| **01. Foundations** | The Building Blocks | Variables, Data Types, Operators, Control Flow | -| **02. Logic & Data** | Organizing Code | Functions, Arrays, Objects, Prototypes | -| **03. The Browser** | Interaction | DOM, Events, Web APIs, Local Storage | -| **04. Mastery** | Advanced Patterns | Async/Await, Promises, Closures, Modules | - -## Start Your Engines - -Let's verify your environment. Below is a live interactive editor. You can modify the code and click **Run** to see the output instantly. - - - - {firstExample} - - -## Is This For You? - -This tutorial is built for **anyone** looking to professionalize their coding skills: -* **Aspiring Developers** looking for a solid career foundation. -* **Self-taught Coders** wanting to fill in the "knowledge gaps." -* **Engineers** switching from other languages like Python or C++. - -## Prerequisites - -You don't need to be a math genius, but you do need: -1. **A Modern Browser**: Chrome, Firefox, or Brave. -2. **A Curiosity Mindset**: Be prepared to experiment and fail fast. -3. **Basic HTML/CSS knowledge**: Helpful, but not strictly required. - -## Knowledge Check - -Let's test your setup. Try to declare your first variables in the "Solution" block below. - -### Exercise: The Identity Challenge -1. Create a variable `name` and assign your name as a string. -2. Create a variable `age` and assign a number. -3. Log them to the console. - -
-👉 View Solution - -```javascript title="solution.js" -const name = "JavaScript Master"; -let age = 25; - -console.log(name); -console.log(age); -``` - -
- -**Congratulations!** You've completed your first JavaScript exercise.🎉 \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 2a4efcf..234b4d9 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -7,27 +7,15 @@ const rehypeKatex = require("rehype-katex"); // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { - title: "JS Mastery", - tagline: "JavaScript Mastery Learning", + title: "JavaScript Mastery", + tagline: "Master Modern JavaScript & Open Source Software Engineering", favicon: "img/js.svg", - - // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future - // future: { - // v4: true, // Improve compatibility with the upcoming Docusaurus v4 - // }, - - // Set the production url of your site here - url: "https://javascript-mastery.github.io", - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: "/", - - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: "javascript-mastery", // Usually your GitHub org/user name. - projectName: "JavaScript Mastery", // Usually your repo name. - - onBrokenLinks: "throw", + url: 'https://javascript-mastery.github.io', + baseUrl: '/', + organizationName: 'javascript-mastery', + projectName: 'javascript-mastery.github.io', + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', // Even if you don't use internationalization, you can use this field to set // useful metadata like html lang. For example, if your site is Chinese, you @@ -46,7 +34,7 @@ const config: Config = { // Please change this to your repo. // Remove this to remove the "edit this page" links. editUrl: - "https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/", + "#", }, blog: { showReadingTime: true, @@ -57,7 +45,7 @@ const config: Config = { // Please change this to your repo. // Remove this to remove the "edit this page" links. editUrl: - "https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/", + "#", // Useful options to enforce blogging best practices onInlineTags: "warn", onInlineAuthors: "warn", @@ -87,67 +75,47 @@ const config: Config = { respectPrefersColorScheme: true, }, navbar: { - title: "JS Mastery", - logo: { - alt: "JS Mastery Logo", - src: "img/js.svg", - }, + title: 'JS Mastery', + logo: { alt: 'JS Mastery Logo', src: 'img/js.svg' }, items: [ - // { - // type: "docSidebar", - // sidebarId: "tutorialSidebar", - // position: "left", - // label: "Tutorial", - // }, + { to: '/docs', label: 'Docs', position: 'left' }, { to: "/tutorial", label: "Tutorial", position: "left" }, - { to: "/blog", label: "Blog", position: "left" }, + { to: '/blog', label: 'Blog', position: 'left' }, + { to: '/faq', label: 'FAQ', position: 'left' }, + { to: '/about', label: 'About', position: 'left' }, + { to: '/contact', label: 'Contact', position: 'left' }, { - href: "#", - label: "GitHub", - position: "right", + href: 'https://github.com/javascript-mastery', + label: 'GitHub', + position: 'right', }, ], - }, + }, footer: { - style: "dark", + style: 'dark', links: [ { - title: "Docs", + title: 'Curriculum', items: [ - { - label: "Tutorial", - to: "/docs/", - }, + { label: 'JavaScript', to: '/docs' }, + { label: 'Tutorial', to: '/tutorial' }, + { label: 'Blog Articles', to: '/blog' }, ], }, { - title: "Community", + title: 'Company & Compliance', items: [ - { - label: "Stack Overflow", - href: "https://stackoverflow.com/questions/tagged/docusaurus", - }, - { - label: "Discord", - href: "https://discordapp.com/invite/docusaurus", - }, - { - label: "X", - href: "https://x.com/docusaurus", - }, + { label: 'About Us', to: '/about' }, + { label: 'Contact Us', to: '/contact' }, + { label: 'FAQ', to: '/faq' }, + { label: 'Privacy Policy', to: '/privacy-policy' }, + { label: 'Terms of Service', to: '/terms' }, ], }, { - title: "More", + title: 'Community', items: [ - { - label: "Blog", - to: "/blog", - }, - { - label: "GitHub", - href: "https://github.com/facebook/docusaurus", - }, + { label: 'GitHub', href: 'https://github.com/javascript-mastery' }, ], }, ], diff --git a/src/components/BlogGrid.jsx b/src/components/BlogGrid.jsx new file mode 100644 index 0000000..e10d0ec --- /dev/null +++ b/src/components/BlogGrid.jsx @@ -0,0 +1,96 @@ +import React from 'react'; + +const blogPosts = [ + { + id: 1, + title: 'Building Modern UI Architectures', + description: 'Learn how to construct clean, scalable component structures with modern React patterns.', + date: 'Sep 01, 2026', + readTime: '5 min read', + tags: ['React', 'UI/UX'], + image: 'https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=600&q=80', + author: { name: 'Ajay Dhangar', avatar: 'https://github.com/ajay-dhangar.png' }, + }, + // Add more posts here... +]; + +export default function BlogGrid() { + return ( +
+ {/* Header Section */} +
+

+ Latest Blog Posts +

+

+ Articles, guides, and tutorials on modern web engineering. +

+
+ + {/* Card Grid */} +
+ {blogPosts.map((post) => ( +
+ {/* Card Banner Image */} + {post.image && ( +
+ {post.title} +
+ )} + + {/* Content Container */} +
+
+ {/* Category Tags */} +
+ {post.tags.map((tag) => ( + + {tag} + + ))} +
+ + {/* Title */} +

+ {post.title} +

+ + {/* Excerpt */} +

+ {post.description} +

+
+ + {/* Author Footer */} +
+ {post.author.name} +
+

+ {post.author.name} +

+

+ {post.date} • {post.readTime} +

+
+
+
+
+ ))} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index 03e26e3..0000000 --- a/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. - - ), - }, - { - title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. - - ), - }, - { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. - - ), - }, -]; - -function Feature({title, Svg, description}: FeatureItem) { - return ( -
-
-
- -
-
- {title} -

{description}

-
-
-
- ); -} - -export default function HomepageFeatures(): ReactNode { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/src/components/HomepageFeatures/styles.module.css b/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index dfbda83..0000000 --- a/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - width: 100px; - height: auto; -} diff --git a/src/components/sections/HeroSection.tsx b/src/components/sections/HeroSection.tsx index 9ff7288..f68cbc2 100644 --- a/src/components/sections/HeroSection.tsx +++ b/src/components/sections/HeroSection.tsx @@ -44,8 +44,8 @@ export const HeroSection: React.FC = () => { {/* Primary Actions */}
- +
+ ) : ( +
+
+
+ + setFormData({ ...formData, name: e.target.value })} + className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl px-4 py-3 text-slate-900 dark:text-slate-100 focus:outline-none focus:ring-2 focus:ring-amber-500 transition-all" + placeholder="Alex Developer" + /> +
+
+ + setFormData({ ...formData, email: e.target.value })} + className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl px-4 py-3 text-slate-900 dark:text-slate-100 focus:outline-none focus:ring-2 focus:ring-amber-500 transition-all" + placeholder="alex@example.com" + /> +
+
+ +
+ + +
+ +
+ +