{"id":29289784,"url":"https://github.com/ahadalireach/javascript.interview.questions","last_synced_at":"2025-08-02T23:08:29.362Z","repository":{"id":302492324,"uuid":"1009799839","full_name":"ahadalireach/javascript.interview.questions","owner":"ahadalireach","description":"A repository containing JavaScript concepts with interview questions, code implementations, and practical examples for learning and interviews.","archived":false,"fork":false,"pushed_at":"2025-07-02T16:47:15.000Z","size":2508,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-02T17:41:17.517Z","etag":null,"topics":["javascript","javascript-concepts","javascript-interview-questions","javascript-interview-questions-and-answers"],"latest_commit_sha":null,"homepage":"https://ahadali.me","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahadalireach.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-27T18:24:48.000Z","updated_at":"2025-07-02T16:47:18.000Z","dependencies_parsed_at":"2025-07-02T17:51:51.781Z","dependency_job_id":null,"html_url":"https://github.com/ahadalireach/javascript.interview.questions","commit_stats":null,"previous_names":["ahadalireach/javascript.interview.questions"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ahadalireach/javascript.interview.questions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahadalireach%2Fjavascript.interview.questions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahadalireach%2Fjavascript.interview.questions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahadalireach%2Fjavascript.interview.questions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahadalireach%2Fjavascript.interview.questions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahadalireach","download_url":"https://codeload.github.com/ahadalireach/javascript.interview.questions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahadalireach%2Fjavascript.interview.questions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268470799,"owners_count":24255391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","javascript-concepts","javascript-interview-questions","javascript-interview-questions-and-answers"],"created_at":"2025-07-06T05:06:39.993Z","updated_at":"2025-08-02T23:08:29.345Z","avatar_url":"https://github.com/ahadalireach.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# JavaScript Interview Questions and Answers\n\n---\n\n## ❓ What is JavaScript?\n\nJavaScript is a **high-level**, **interpreted**, **single-threaded**, and **synchronous** programming language used to create interactive websites.\n\nIt runs in the browser and can also be used on the backend (Node.js).\n\n- **High-level:** Easy to read and write, handles low-level stuff for you.\n- **Interpreted:** Runs code line by line in the browser.\n- **Single-threaded:** Can do one thing at a time.\n- **Synchronous:** Executes code in order, one step after another.\n\n### But JavaScript Can Also Be Asynchronous:\n\nJS uses tools like:\n\n- `setTimeout()`\n- **Web APIs**\n- **Promises**\n- `async/await`\n\n...to run code in the background without blocking.\n\n---\n\n## ❓ What is the History of JavaScript?\n\nJavaScript was created by **Brendan Eich** in **1995** while working at Netscape.\n\n- Originally called **Mocha**, then renamed to **LiveScript**, and finally **JavaScript**.\n- It was developed in just **10 days**.\n- Despite the name, JavaScript is **not related to Java**.\n- Standardized by **ECMA International** as **ECMAScript** in 1997.\n- Today, JavaScript is one of the **core technologies of the web** alongside HTML and CSS.\n\n---\n\n## ❓ Is JavaScript a Compiled or Interpreted Language?\n\nFirst of all let's understand what is:\n\n### What is a JavaScript Engine?\n\nA **JavaScript Engine** is a program that executes JavaScript code.\n\n- **V8** — Used in Chrome and Node.js\n- **SpiderMonkey** — Used in Firefox\n- **Chakra** — Used in older Microsoft Edge versions\n\n### Is JavaScript Compiled or Interpreted?\n\nTraditionally, **JavaScript is an interpreted language**, meaning:\n\n- Code is executed **line by line**.\n- Earlier engines interpreted JS **without converting to machine code ahead of time**.\n\nBut **modern JavaScript engines** use **JIT (Just-In-Time) Compilation**, which makes JavaScript **partially compiled** and **partially interpreted**.\n\n```js\nconsole.log(\"Hello World\"); // Runs first\nconsole.log(\"Hello Again\"); // Runs after the first line\n```\n\n\u003e So, JavaScript behaves like an interpreted language but with **JIT compilation** to boost performance.\n\n### What is an Abstract Syntax Tree (AST)?\n\nAn **Abstract Syntax Tree (AST)** is a tree-like representation of the source code structure.\n\n- Nodes represent constructs like variables, functions, operators, etc.\n\n- AST is used internally by JavaScript engines for:\n\n  - Syntax checking\n  - Scope management\n  - Code transformation and optimization\n\n### 🆚 Compiled vs Interpreted Languages\n\n| **Feature**    | **Compiled Languages**       | **Interpreted Languages**       |\n| -------------- | ---------------------------- | ------------------------------- |\n| **Examples**   | C, C++, Rust                 | JavaScript, Python, Ruby        |\n| **Execution**  | Pre-compiled to machine code | Line-by-line execution          |\n| **Speed**      | Faster after compilation     | Slower at runtime               |\n| **Start Time** | Slower to start              | Fast to start                   |\n| **Output**     | Machine code                 | Direct execution by interpreter |\n\n### How Modern JavaScript Works (JIT)\n\nModern engines like **V8** use **Just-In-Time (JIT) Compilation**:\n\n- JS is parsed into an **AST (Abstract Syntax Tree)**\n- Then it's compiled into **bytecode**\n- \"Hot code\" (frequently used code) is **optimized into machine code** during runtime\n\n👉 This gives JavaScript the **speed of compiled languages**\nwhile keeping the **flexibility of interpreted ones**\n\n### Analogy\n\n- **Interpreted**: Reading a book out loud word by word without preparation\n- **Compiled**: Translating the book entirely before reading\n- **JIT**: Reading out loud and translating parts as you go for speed and efficiency\n\n---\n\n## ❓ What Makes JavaScript Great?\n\nJavaScript is popular for a reason. It’s powerful, flexible, and beginner-friendly.\n\n### Key Reasons:\n\n- **Simplicity:**\n  Easy to learn, write, and run directly in the browser. No setup needed.\n\n- **Versatility:**\n  Works on the **frontend** (browser), **backend** (Node.js), and even in **mobile apps** (React Native).\n\n- **OOP + Functional Programming:**\n  Supports both:\n\n  - **Object-Oriented Programming** (classes, objects, inheritance)\n  - **Functional Programming** (first-class functions, callbacks)\n\n- **Asynchronous Power:**\n  Handles slow tasks like API calls using:\n\n  - Callbacks\n  - Promises\n  - `async/await`\n\n- **Huge Ecosystem:**\n  Massive community, lots of libraries and frameworks like:\n  - React\n  - Angular\n  - Vue\n\n---\n\n## ❓ What Are JavaScript's Weaknesses?\n\nEven though JavaScript is powerful and popular, it has some limitations.\n\n### Key Weaknesses:\n\n- **Security Issues:**\n  JavaScript runs on the client side, so it’s exposed to attacks like XSS (Cross-Site Scripting).\n\n- **Browser Dependency:**\n  Behavior may vary across browsers due to differences in engine implementations.\n\n- **Single-threaded:**\n  It can only do one thing at a time. Heavy tasks can block the UI and make the page unresponsive.\n\n- **Global Scope Pollution:**\n  If not carefully managed, too many global variables can cause conflicts.\n\n- **Debugging Async Code:**\n  Debugging Promises or `async/await` can be tricky, especially for beginners.\n\n---\n\n## ❓ What is JSON?\n\n**JSON** stands for **JavaScript Object Notation**\n\nIt’s a:\n\n- Lightweight\n- Self-descriptive\n- Easy-to-read\n\nA **data format used for exchanging data between server and client**\n\n### JSON Object Example\n\n```json\n{\n  \"name\": \"Ahad Ali\",\n  \"age\": 22,\n  \"isDeveloper\": true,\n  \"skills\": [\"JavaScript\", \"React\"],\n  \"profile\": {\n    \"linkedin\": \"ahadalireach\",\n    \"location\": \"Pakistan\"\n  }\n}\n```\n\n### `JSON.parse()` — Convert JSON String → JS Object\n\nUse when you **receive JSON from a server** (as a string) and want to convert it to a **JavaScript object**.\n\n```js\nconst jsonData = '{\"name\":\"Ahad\",\"age\":22}';\nconst obj = JSON.parse(jsonData);\n\nconsole.log(obj.name); // ✅ \"Ahad\"\n```\n\n- `JSON.parse()` ka use tab hota hai jab string ko JavaScript object mein convert karna ho.\n\n### `JSON.stringify()` — Convert JS Object → JSON String\n\nUse when you want to send data to a server.\nServer string hi accept karta hai, is liye object ko string banana padta hai.\n\n```js\nconst obj = { name: \"Ahad\", age: 22 };\nconst jsonString = JSON.stringify(obj);\n\nconsole.log(jsonString); // ✅ '{\"name\":\"Ahad\",\"age\":22}'\n```\n\n- `JSON.stringify()` se hum JS object ko JSON string bana kar send karte hain.\n\n---\n\n## ❓ What is a Thread of Execution?\n\nA **thread of execution** is the path a program follows while running your code — one line at a time.\n\nIn simple terms, a thread is a **single, sequential flow** of instructions.\n\n### In JavaScript:\n\n- JavaScript is **single-threaded**, meaning it has only **one main thread** to execute all code.\n- Everything runs **line by line** — one task at a time.\n- This thread manages two main things:\n  - **Call Stack:** Tracks function calls and execution order.\n  - **Memory Heap:** Stores variables and objects.\n\n### In Simple Words:\n\n\u003e It’s **how JavaScript runs your code from top to bottom, one step at a time.**\n\n```js\nconsole.log(\"1\");\nconsole.log(\"2\");\nconsole.log(\"3\");\nconsole.log(\"4\");\n```\n\n```\n1\n2\n3\n4\n```\n\n![Execution of Thread](thread.png)\n\nJavaScript executes one statement, then moves to the next — just like reading a book.\n\n---\n\n## ❓ What is the Call Stack?\n\nThe **Call Stack** is a data structure that JavaScript uses to **keep track of function calls**.\n\nIt follows the **LIFO (Last In, First Out)** principle.\nThe last function that enters the stack is the first one to finish and be removed.\n\n\u003e The Call Stack is like a **to-do list** for functions.\n\u003e JavaScript keeps track of \"what to run next\" using this stack.\n\n\u003e The call stack manages **function execution one by one**.\n\u003e New function calls are added on top. When a function finishes, it's removed from the top.\n\u003e The **Global Execution Context** is always at the bottom.\n\n\u003e Any code must go through the **call stack** before it gets executed.\n\n```js\nfunction first() {\n  console.log(\"first...\");\n  second();\n}\n\nfunction second() {\n  console.log(\"second...\");\n  third();\n}\n\nfunction third() {\n  console.log(\"third...\");\n}\n\n// Calling out of order\nthird();\nsecond();\nfirst();\n```\n\n### Step-by-Step Breakdown\n\n1. `third()` is called:\n\n```console\nthird...\n```\n\n- `third()` is pushed to the call stack\n- It executes and prints \"third...\"\n- Then it is popped off after execution\n\n2. `second()` is called:\n\n```console\nsecond...\nthird...\n```\n\n- `second()` is pushed to the call stack\n- It calls `third()` → `third()` is pushed\n- `third()` executes and is popped\n- Then `second()` finishes and is popped\n\n3. `first()` is called:\n\n```console\nfirst...\nsecond...\nthird...\n```\n\n- `first()` is pushed to the call stack\n- It calls `second()` → pushed\n- `second()` calls `third()` → pushed\n- Then they finish in reverse:\n  - `third()` → popped\n  - `second()` → popped\n  - `first()` → popped\n\n### How It Works\n\n\u003e Every time a function is called, it is **pushed** onto the **Call Stack**.\n\u003e When it finishes, it is **popped off**.\n\n| Before Execution                                      | Nested Calls in Stack                                 |\n| ----------------------------------------------------- | ----------------------------------------------------- |\n| \u003cimg src=\"callstack1.png\" width=\"400\" height=\"400\" /\u003e | \u003cimg src=\"callstack2.png\" width=\"400\" height=\"400\" /\u003e |\n\n---\n\n## ❓ What is Execution Context?\n\nThe **Execution Context** is like a **workspace** or **container** where JavaScript runs your code.\n\nWhenever your code runs, a new execution context is created.\nThis environment handles the **transformation and execution** of your code and contains all the info JavaScript needs to run it properly.\n\n\u003e Everything in JavaScript runs **inside an execution context**.\n\n### Components of Execution Context:\n\n1. **Memory Component (Creation Phase / Variable Environment):**\n\n   - Stores variables and function declarations\n   - Sets up the scope chain\n   - Binds the `this` keyword\n\n2. **Code Component (Execution Phase / Thread of Execution):**\n   - Executes code line-by-line\n   - Runs function logic and expressions\n\n### Visual Representation:\n\n| Memory Phase                                   | Execution Phase                                |\n| ---------------------------------------------- | ---------------------------------------------- |\n| \u003cimg src=\"ec1.png\" width=\"400\" height=\"400\" /\u003e | \u003cimg src=\"ec2.png\" width=\"400\" height=\"400\" /\u003e |\n\n\u003cimg src=\"ec.png\" width=\"100%\" height=\"400\" /\u003e\n\n### Types of Execution Context:\n\n- **Global Execution Context (GEC):**\n\n  - Created by default when JavaScript starts executing your file\n  - Only one GEC exists at a time\n\n- **Function Execution Context (FEC):**\n\n  - Created **every time a function is called**\n  - Each has its own memory and code components\n\n- **Eval Execution Context (EEC):**\n  - Rare and created when code is run using `eval()`\n\n\u003e JavaScript uses the **Call Stack** to manage all execution contexts.First, the **Global Execution Context (GEC)** is pushed.Every time a function is called, a new **Function Execution Context (FEC)** is pushed on top.As each function completes, its context is popped off — one by one.\n\n---\n\n## ❓ What is the Global Execution Context (GEC)?\n\nThe **Global Execution Context (GEC)** is the first environment created when JavaScript starts running your code.\nIt represents the **global scope** and provides a base where all global code runs.\n\n- **Created automatically** when the script begins execution\n- Stores all **global variables** and **function declarations**\n- Sets up the **global object** and binds `this` to it\n- Only **one GEC** exists at any given time\n\n### Two Phases of GEC:\n\n1. **Memory Creation Phase (Hoisting):**\n\n   - All variables are allocated memory and initialized with `undefined`\n   - Function declarations are stored entirely\n\n2. **Execution Phase:**\n   - Code is executed **line-by-line**\n   - Variables are assigned actual values\n\n### What is the Global Object?\n\nThe **global object** is a special object that holds all global-level variables and functions.\n\n- In **browsers**, it's called `window`\n- In **Node.js**, it's called `global`\n\n```js\nvar a = 10;\n\nconsole.log(a); // Output: 10\nconsole.log(window.a); // Output: 10 (in browsers)\nconsole.log(global.a); // Output: 10 (in Node.js)\n```\n\n\u003e The value of `this` inside the Global Execution Context points to the global object.\n\n---\n\n## ❓ What is Function Execution Context (FEC)?\n\nThe **Function Execution Context (FEC)** is created **every time a function is invoked** in JavaScript.\nIt is a private environment used to run the specific function’s code.\n\nEach FEC contains:\n\n- Arguments object\n- Local variable scope\n- Reference to outer environment\n\nEach function call creates a new execution context that is:\n\n- **Pushed onto the call stack**\n- **Executed**\n- **Popped off** once the function completes\n\n\u003e This context is **temporary** and exists only during the lifetime of the function execution.\n\n```js\nlet a = 10; // Global variable\nlet b = 20; // Global variable\n\nfunction add(a, b) {\n  return a + b; // Executes inside FEC\n}\n\nlet result = add(a, b); // Creates FEC\nconsole.log(result); // Output: 30\n```\n\n\u003e Each function runs in its own **isolated context** and then returns control back to the previous context (usually GEC).\n\n---\n\n## ❓ What is Eval Execution Context (EEC)?\n\nThe **Eval Execution Context (EEC)** is created whenever JavaScript runs code using the `eval()` function.\n\nIt behaves similarly to other execution contexts, with its own memory and execution phase, but is considered dangerous and discouraged.\n\n- Created when `eval()` is used to **execute a string of code**\n- Has its own **execution context and variable environment**\n- Can introduce or override global variables\n- **Rarely used** due to **security** and **performance** issues\n\n```js\neval(\"var a = 10;\"); // Creates Eval Execution Context\nconsole.log(a); // Output: 10 (in global scope)\n```\n\n\u003e ⚠️ Avoid using `eval()` in production. It can lead to vulnerabilities and unpredictable behavior.\n\n---\n\n## ❓ What is Scope? What are its Types?\n\nScope determines where variables can be **accessed** in your code.\nIt defines the **visibility** and **lifetime** of variables.\n\n\u003e The region where we can access the variable is known as the scope for that variable.\n\n### JavaScript supports 4 types of scope:\n\n- **Global Scope**\n- **Function Scope**\n- **Block Scope**\n- **Module Scope**\n\n### Global Scope:\n\n- Variables declared **outside** of any function or block are in the global scope\n- Accessible throughout the file and other files (if attached to the global object)\n- In the browser, the global object is `window`; in Node.js, it's `global`\n\n```js\nvar a = 10;\nconsole.log(window.a); // 10 in browser\n```\n\n```js\nfunction sayHi() {\n  console.log(this); // refers to window in non-strict mode\n}\n```\n\n### Module Scope:\n\n- Each JavaScript module (using `import`/`export`) has its own scope\n- Variables/functions declared in a module are not global unless explicitly exported\n\n```js\n// index.js\nexport const name = \"Ahad\";\n\n// app.js\nimport { name } from \"./index.js\";\nconsole.log(name);\n```\n\n### Function Scope:\n\n- Each time a function is called, a new scope is created\n- Variables declared with `var` inside functions are scoped to that function\n\n```js\nfunction sayHi(name) {\n  var greeting = \"Hi \" + name;\n  return greeting;\n}\n\nconsole.log(sayHi(\"Ahad\"));\n```\n\n### Block Scope:\n\n- Introduced with ES6 using `let` and `const`\n- Variables declared inside `{}` (e.g. in `if`, `for`) are block-scoped\n\n```js\n{\n  let x = 5;\n  const y = 10;\n  console.log(x, y);\n}\n// x and y are not accessible here\n```\n\n\u003e Always prefer `let` and `const` for safer, block-scoped variables.\n\n---\n\n## ❓ What is Scope Chain, Lexical Scope, and Lexical Environment?\n\n### Scope Chain\n\nThe **Scope Chain** is the process JavaScript uses to **resolve variable names**.\n\n- When a variable is referenced, the JS engine looks in the **current scope**.\n- If not found, it goes **upward** to the **parent scopes**, all the way to the **global scope**.\n- This forms a \"chain\" of scopes.\n\n```js\nlet a = 10;\n\nfunction outer() {\n  let b = 20;\n\n  function inner() {\n    let c = 30;\n    console.log(a); // ✅ 10 (from global scope)\n    console.log(b); // ✅ 20 (from outer)\n    console.log(c); // ✅ 30 (own scope)\n  }\n\n  inner();\n}\n\nouter();\n```\n\n\u003e Scope Chain Order:\n\n- Inner function scope\n- Outer function scope\n- Global scope\n\n`OR`\n\n**Scope chain** is how JavaScript looks for variables:\n👉 If a variable is not found in the current scope, JS looks outward in the parent scope — until it reaches the global scope.\n\n```js\nlet a = \"Global\";\n\nfunction outer() {\n  let b = \"Outer\";\n\n  function inner() {\n    let c = \"Inner\";\n    console.log(a); // ✅ Looks in global\n    console.log(b); // ✅ Looks in outer\n    console.log(c); // ✅ Local\n  }\n\n  inner();\n}\n\nouter();\n```\n\n\u003e Concept: The inner function has access to variables of its outer functions due to scope chain.\n\n### Lexical Scope\n\n**Lexical Scope** (also called static scope) means:\n\n- A variable's accessibility is determined by its position in the source code, not where it is called.\n- Functions defined inside other functions can access variables from their outer scopes.\n\n```js\nlet globalVar = \"Global\";\n\nfunction outerFunction() {\n  let outerVar = \"Outer\";\n\n  function innerFunction() {\n    console.log(globalVar); // ✅ Accesses global\n    console.log(outerVar); // ✅ Accesses outer\n  }\n\n  innerFunction();\n}\n\nouterFunction();\n```\n\n\u003e Lexical scope is set when you write the function, not when you call it.\n\n`OR`\n\nLexical scope ka matlab hai:\n\n- \"Function kis jagah likha gaya hai, uss jagah ke variables us function ke liye available honge.\"\n- Yeh likhne ke waqt decide hota hai, run-time par nahi.\n\n**Easy Explanation:**\nAgar koi function kisi aur function ke andar likha ho, to wo apne parent function ke variables ko access kar sakta hai, even agar wo baad mein kahin aur call ho.\n\n```js\nfunction outer() {\n  let name = \"Ahad\"; // 👈 outer scope variable\n\n  function inner() {\n    console.log(name); // ✅ Accesses outer's variable\n  }\n\n  return inner; // 👈 inner function ko return kar dia\n}\n\nconst greet = outer(); // outer() run hoke inner() return hua\ngreet(); // inner() run hua\n```\n\n**Kya hua yahaan?**\n\n- `inner()` function outer ke andar likha gaya tha.\n- To usko outer ka variable name mil gaya.\n- Chahe `inner()` function baad mein kahin aur se call ho — scope wahi hoga jahan wo likha gaya tha.\n\n### Lexical Environment\n\nA **Lexical Environment** is an internal structure used by JS to track identifiers (variables/functions) during execution.\n`OR`\nA **Lexical Environment** is a concept used by JS engine to manage scope.\n\n\u003e Every time a function is called, a new Lexical Environment is created for it.\n\n**Components:**\n\n- Environment Record – Stores variable/function declarations\n- Outer Environment Reference – Links to the parent Lexical Environment\n\n```js\nfunction sum(x) {\n  return function (y) {\n    return x + y;\n  };\n}\n\nconst add5 = sum(5); // x = 5 in this Lexical Environment\nconsole.log(add5(10)); // 15\n```\n\n- Here, the inner function remembers `x = 5` even after sum has finished running, because of the lexical environment.\n\n`OR`\n\nJab **JavaScript** koi function run karti hai, wo ek box banati hai (Environment) jisme:\n\n- Saare variables store hote hain\n- Aur reference hota hai outer scope ka (scope chain)\n\n\u003e Is box ko Lexical Environment kehte hain.\n\n```js\nfunction sum(x) {\n  return function (y) {\n    return x + y;\n  };\n}\n\nconst add5 = sum(5); // yahan ek LE bana jisme x = 5\nconsole.log(add5(10)); // 15 ➡ y = 10, x = 5 already remembered\n```\n\n- `sum(5)` jab call hota hai, JS ek Lexical Environment banata hai jisme:\n  - ` x = 5``\n  - aur ek inner function store hota hai\n- Jab `add5(10)`call hota hai:\n  - `y = 10`hota hai\n  - but`x = 5` already saved tha pehle se (due to lexical environment)\n\n\u003e **Lexical Scoping** “Access Rules”\n\u003e **Lexical Environment** — “Runtime Storage”\n\n| Concept             | Explanation                                                                  |\n| ------------------- | ---------------------------------------------------------------------------- |\n| Scope Chain         | JS searches for a variable from current → outer → global scope               |\n| Lexical Scope       | Scope is based on **where** a function is **written**, not where it’s called |\n| Lexical Environment | Behind-the-scenes structure: record of variables + link to parent scope      |\n\n### Real-World Analogy\n\n\u003e **Scope Chain** = \"Search path for variables\"\n\u003e **Lexical Scope** = \"Where the function is written decides what it sees\"\n\u003e **Lexical Environment** = \"Notebook that tracks variables + a link to its parent notebook\"\n\n---\n\n## ❓ What is Closure?\n\n\u003e A **closure** is a function that retains access to its outer function's variables even after the outer function has completed execution.\n\nIn simple terms:\n\n- A function “remembers” the scope in which it was created.\n- Even after the outer function is done executing, the inner function still has access to the variables of the outer function.\n\n\u003e A closure is a combination of a function and its **lexical environment** (the variables in scope when the function was created).\n\n### How Closure Works?\n\n```js\n// Simple Closure\nfunction makeCounter() {\n  let count = 0;\n  return function () {\n    count++;\n    return count;\n  };\n}\n\nconst counter = makeCounter();\nconsole.log(counter()); // 1\nconsole.log(counter()); // 2\nconsole.log(counter()); // 3\n```\n\n- The inner function “remembers” count from its `outer` lexical environment.\n- Even though `makeCounter()` has finished executing, `count` is still accessible.\n\n### Real-World Example: Button Counter\n\n```js\nfunction initCounter(id) {\n  let count = 0;\n  return function () {\n    count++;\n    document.getElementById(id).innerText = count;\n  };\n}\n\nlet counter1 = initCounter(\"btnCount1\");\nlet counter2 = initCounter(\"btnCount2\");\n```\n\n```html\n\u003cbutton onclick=\"counter1()\"\u003e1\u003c/button\u003e\n\u003cp id=\"btnCount1\"\u003e\u003c/p\u003e\n\n\u003cbutton onclick=\"counter2()\"\u003e2\u003c/button\u003e\n\u003cp id=\"btnCount2\"\u003e\u003c/p\u003e\n```\n\n- Each button click updates a **private counter**, and both counters are independent.\n\n### Real-World Example: String Appender\n\n```js\nfunction initAddString(inputId, outputId) {\n  let str = \"\";\n  return function () {\n    str += \" \" + document.getElementById(inputId).value;\n    document.getElementById(inputId).value = \"\";\n    document.getElementById(outputId).innerText = str;\n  };\n}\n\nlet strAdder1 = initAddString(\"text1\", \"text-output1\");\nlet strAdder2 = initAddString(\"text2\", \"text-output2\");\n```\n\n```html\n\u003cinput type=\"text\" id=\"text1\" /\u003e\n\u003cbutton onclick=\"strAdder1()\"\u003eAdd String\u003c/button\u003e\n\u003cp id=\"text-output1\"\u003e\u003c/p\u003e\n\n\u003cinput type=\"text\" id=\"text2\" /\u003e\n\u003cbutton onclick=\"strAdder2()\"\u003eAdd String\u003c/button\u003e\n\u003cp id=\"text-output2\"\u003e\u003c/p\u003e\n```\n\n- Each button maintains its own string state separately using closures.\n\n### Advantages of Closures:\n\n1. **Data Privacy**\n\nClosures enable private variables that are not accessible from outside.\n\n```js\nfunction privateCounter() {\n  let count = 0;\n\n  function incrementCount() {\n    return count++;\n  }\n\n  function getCount() {\n    return count;\n  }\n\n  return { incrementCount, getCount };\n}\n\nlet counter = privateCounter();\nconsole.log(counter.getCount()); // 0\ncounter.incrementCount();\nconsole.log(counter.getCount()); // 1\n```\n\n2. **Maintain State**\n\nFunctions can remember their outer scope, allowing state to persist.\n\n```js\nfunction call() {\n  let time = 1;\n\n  function timer() {\n    return time++;\n  }\n\n  return timer;\n}\n\nlet timer = call();\nconsole.log(timer()); // 1\nconsole.log(timer()); // 2\nconsole.log(timer()); // 3\n```\n\n3. **Factorize Functions**\n\nClosures help create functions that remember and use values across calls. `OR` Closures allow you to create customized functions.\n\n```js\nfunction multiplier(factor) {\n  return function (num) {\n    return factor * num;\n  };\n}\n\nlet double = multiplier(2);\nlet triple = multiplier(3);\n\nconsole.log(double(10)); // 20\nconsole.log(triple(10)); // 30\n```\n\n### Disadvantages of Closures:\n\n1. **Memory Consumption**\n\nClosures retain references to their outer scope, which can increase memory usage if not managed well.\n\n2. **Performance Issues**\n\nExcessive use of closures may reduce performance due to increased memory usage.\n\n3. **Debugging Challenges**\n\nClosures can complicate debugging due to complex scope chains.\n\n\u003e Closure = (Inner) Function + Outer Variables (Preserved)\n\n---\n\n## ❕ Bonus Question\n\n### ❓ Question: How can you optimize this expensive function?\n\nYou're given the following code:\n\n```js\nconst clumsySquare = (num1, num2) =\u003e {\n  for (let i = 1; i \u003c= 100000000; i++) {} // simulate heavy processing\n  return num1 * num2;\n};\n```\n\n**Problem:**\n- The function takes a long time to run due to the artificial delay.\n- Calling it repeatedly with the **same arguments** will re-run the delay every time.\n\n#### How can you make it faster?\n**💡 Solution: Use Memoization**\n\n\u003e Memoization caches the result for a given set of inputs,\n\u003e so if you call the function again with the same arguments,\n\u003e it returns the cached result instantly, skipping recomputation.\n\n**Memoized Version**\n```js\nfunction myMemoize(fn, context) {\n  const res = {}; // cache storage\n  return function (...args) {\n    const argsCache = JSON.stringify(args); // key from args\n    if (!res[argsCache]) {\n      console.log(\"Calculating...\", args);\n      res[argsCache] = fn.apply(context || this, args);\n    }\n    return res[argsCache];\n  };\n}\n```\n```js\n// Apply Memoization to clumsySquare\nconst clumsySquare = (num1, num2) =\u003e {\n  for (let i = 1; i \u003c= 100000000; i++) {} // simulate heavy work\n  return num1 * num2;\n};\n\nconst memoizedSquare = myMemoize(clumsySquare);\nconsole.time(\"First call\");\nconsole.log(memoizedSquare(9467, 7649)); // Slow: runs the loop\nconsole.timeEnd(\"First call\");\n\nconsole.time(\"Second call\");\nconsole.log(memoizedSquare(9467, 7649)); // Fast: returns cached result\nconsole.timeEnd(\"Second call\");\n\n```\n\n- 🐌 Without memoization: Every call does expensive work\n- ⚡ With memoization: Repeated calls are near-instant\n- 👏 A simple yet powerful optimization using closures + lexical scope\n\n---\n\n## ❓ How Does Memory Management Work in JavaScript?\n\nJavaScript handles memory using two main components:\n\n- **Stack**: For static, fixed-size data (primitive types)\n- **Heap**: For dynamic, complex data (reference types)\n\n### Stack Memory (for Primitive Types)\n\n**Stores:**\n\n- Numbers, strings, booleans, `undefined`, `null`, `symbol`\n- Local variables and function calls\n\n**Characteristics:**\n\n- Fast memory access (LIFO - Last In First Out)\n- Memory is allocated linearly\n- Values are copied (changes do not affect other variables)\n- Automatically managed during function execution\n\n```js\nlet num = 10; // Primitive stored in stack\nlet str = \"Hello\"; // Primitive stored in stack\n\nfunction add(x, y) {\n  let sum = x + y; // Local variables stored in stack\n  return sum;\n}\n```\n\n### Heap Memory (for Reference Types)\n\n**Stores:**\n\n- `Objects`, `arrays`, and `functions` (non-primitive types)\n\n**Characteristics:**\n\n- Memory allocated non-linearly\n- Variables store references (not actual data)\n- Slower access than stack\n- Changes via one reference affect all others pointing to the same object\n\n```js\nlet user = { name: \"Ahad\", age: 25 }; // Stored in heap\nlet arr = [1, 2, 3]; // Stored in heap\n\nlet obj1 = { value: 10 };\nlet obj2 = obj1; // Both point to the same object\n\nobj1.value = 20;\n\nconsole.log(obj2.value); // 20 (both refer to the same object)\n```\n\n### Garbage Collection\n\n**JavaScript engines (like V8)** use automatic garbage collection to manage memory.\n\n- Mark-and-Sweep Algorithm: Removes objects that are no longer accessible or referenced\n- Unreachable memory is cleaned up to free space\n- Developers don't manually manage memory — it's handled behind the scenes\n\n\u003e If an object or value is no longer reachable from the root (window or global), it's marked as garbage and removed.\n\n![Stack vs Heap Memory](memory.png)\n\n---\n\n## ❓ What is the Difference between `var`, `let`, and `const` in JavaScript?\n\nJavaScript provides three ways to declare variables: `var`, `let`, and `const`.\n\nEach behaves differently in terms of:\n\n- Scope\n- Hoisting\n- Redeclaration\n- Reassignment\n- Temporal Dead Zone (TDZ)\n- Use cases\n\n### var\n\n- Function-scoped\n- Can be redeclared and reassigned\n- Hoisted and initialized with `undefined`\n- Avoid in modern JavaScript due to confusing scope behavior\n\n```js\nfunction testVar() {\n  if (true) {\n    var x = 10;\n  }\n  console.log(x); // ✅ 10 (accessible outside the block)\n}\ntestVar();\n```\n\n```js\n// Hoisted and initialized with undefined\nconsole.log(a); // ✅ undefined\nvar a = 5;\n```\n\n```js\n// Can be redeclared in the same scope\nvar d = 100;\nvar d = 200; // ✅ No error\nconsole.log(d); // 200\n```\n\n```js\n// Can be reassigned\nvar g = 10;\ng = 20; // ✅\nconsole.log(g); // 20\n```\n\n```js\n// No TDZ (initialized as undefined)\nconsole.log(j); // ✅ undefined\nvar j = 5;\n```\n\n### let\n\n- Block-scoped\n- Cannot be redeclared in the same scope\n- Can be reassigned\n- Hoisted but not initialized (Temporal Dead Zone applies)\n\n```js\nfunction testLetConst() {\n  if (true) {\n    let y = 20;\n  }\n  console.log(y); // ❌ ReferenceError\n}\ntestLetConst();\n```\n\n```js\n// Hoisted but not initialized (TDZ)\nconsole.log(b); // ❌ ReferenceError\nlet b = 10;\n```\n\n```js\n// Cannot be redeclared in the same scope\nlet e = 1;\nlet e = 2; // ❌ SyntaxError: Identifier 'e' has already been declared\n```\n\n```js\n// Can be reassigned\nlet h = 30;\nh = 40; // ✅\nconsole.log(h); // 40\n```\n\n```js\n// TDZ applies (not accessible before declaration)\nconsole.log(k); // ❌ ReferenceError\nlet k = 10;\n```\n\n### const\n\n- Block-scoped\n- Cannot be redeclared or reassigned\n- Must be initialized at the time of declaration\n- Also subject to Temporal Dead Zone\n\n```js\nfunction testLetConst() {\n  if (true) {\n    const z = 30;\n  }\n  console.log(z); // ❌ ReferenceError\n}\ntestLetConst();\n```\n\n```js\n// Hoisted but not initialized (TDZ)\nconsole.log(c); // ❌ ReferenceError\nconst c = 15;\n```\n\n```js\n// Cannot be redeclared in the same scope\nconst f = 3;\nconst f = 4; // ❌ SyntaxError\n```\n\n```js\n// Cannot be reassigned\nconst i = 50;\ni = 60; // ❌ TypeError: Assignment to constant variable\n```\n\n```js\n// TDZ applies (not accessible before declaration)\nconsole.log(l); // ❌ ReferenceError\nconst l = 15;\n```\n\n\u003e ⚠️ However, `objects` and `arrays` declared with const can be mutated\n\n```js\nconst obj = { name: \"Ahad\" };\nobj.name = \"Ali\"; // ✅ Allowed\nconsole.log(obj.name); // \"Ali\"\n```\n\n### Use Cases\n\n| Keyword | Best Use                                             |\n| ------- | ---------------------------------------------------- |\n| `var`   | ❌ Avoid in modern code                              |\n| `let`   | ✅ When variable needs to change                     |\n| `const` | ✅ For constants or when you don't want reassignment |\n\n```js\nconst API_KEY = \"123-abc\"; // ✅ Use const for constants\nlet score = 0; // ✅ Use let if score may change\n```\n\n---\n\n## ❓ What is Hoisting?\n\nHoisting is a JavaScript behavior where variable and function declarations are moved to the top of their scope during the creation phase, allowing them to be accessed before being defined in the code.\n\n`OR`\n\n**Hoisting** is JavaScript's behavior of moving **declarations** (not initializations) to the top of their scope before execution.\n\n- Works with both variables and functions\n- Variables declared with `var` are hoisted and set to `undefined`\n- `let` and `const` are hoisted but not initialized (Temporal Dead Zone applies)\n- Function declarations are fully hoisted\n\n```js\ngreet(); // ✅ \"Hi\"\n\nfunction greet() {\n  console.log(\"Hi\");\n}\n```\n\n```\nconsole.log(a); // ✅ undefined\nvar a = 10;\n```\n\n```js\nconsole.log(b); // ❌ ReferenceError\nlet b = 20;\n```\n\n\u003e Only declarations are hoisted — initializations stay in place.\n\n---\n\n## ❓ What is the Behaviour of hoisting in case of `var`, `let`, and `const` in JavaScript?\n\n| Declaration | Hoisted | Initialized  | Scope    | TDZ Applies |\n| ----------- | ------- | ------------ | -------- | ----------- |\n| var         | ✅ Yes  | ✅ undefined | Function | ❌ No       |\n| let         | ✅ Yes  | ❌ No        | Block    | ✅ Yes      |\n| const       | ✅ Yes  | ❌ No        | Block    | ✅ Yes      |\n\n```js\nconsole.log(x); // ✅ undefined\nvar x = 10;\n```\n\n```js\nconsole.log(y); // ❌ ReferenceError\nlet y = 20;\n```\n\n```js\nconsole.log(z); // ❌ ReferenceError\nconst z = 30;\n```\n\n\u003e `let` and `const` exist in memory during hoisting but cannot be accessed — this is called the Temporal Dead Zone (TDZ).\n\n![alt text](hoisting.png)\n\n---\n\n## ❓ What is Temporal Dead Zone (TDZ)?\n\nThe **Temporal Dead Zone (TDZ)** is the time between variable hoisting and its declaration/initialization in code.\n\n- Applies to `let` and `const`\n- Does not apply to `var`\n- Variable exists in memory but cannot be accessed yet\n\n```js\nx = 30; // ❌ ReferenceError\nconsole.log(x); // ❌ ReferenceError\nlet x = 10; // ✅ x declared and initialized\n```\n\n\u003e TDZ is \"temporal\" because it depends on the time of execution, not the position of code.\n\n- Prevents accessing variables before intentional initialization\n- Helps catch bugs in larger codebases\n\n---\n\n## ❓ What is Variable Shadowing?\n\n**Variable shadowing** occurs when a variable declared in an inner scope (e.g., inside a block or function) has the **same name** as a variable in an outer scope. The inner variable **\"shadows\"** the outer one, making it inaccessible within that inner scope.\n\n```js\nlet x = 0; // Outer variable (shadowed)\n{\n  let x = 1; // Inner variable (shadows the outer x)\n  console.log(x); // ✅ 1 (refers to inner x)\n}\nconsole.log(x); // ✅ 0 (refers to outer x again)\n```\n\n\u003e ⚠️ Shadowing only affects visibility within the inner scope.\n\n```js\n// Function Scope Example\nlet message = \"Hello\";\n\nfunction greet() {\n  let message = \"Hi\"; // Shadows the outer 'message'\n  console.log(message); // ✅ \"Hi\"\n}\n\ngreet();\nconsole.log(message); // ✅ \"Hello\"\n```\n\n## ❓ What are Functions and there types in JavaScript?\n\nFunctions in JavaScript are blocks of reusable code that perform a specific task.\n\n### Types of Functions in JavaScript:\n\n- Normal (Named) Functions\n- Arrow Functions\n- Function Expressions\n- Anonymous Functions\n- First-Class Functions\n- Call-Back Functions\n- Pure Functions\n\n---\n\n## ❓ What is the Difference between Normal Function and Arrow Function?\n\n1. Syntax\n\n```javascript\n// Normal Function\nfunction add(a, b) {\n  return a + b;\n}\n```\n\n```javascript\n// Arrow Function\nconst add = (a, b) =\u003e a + b;\n\n(a) =\u003e {\n  return a; // Explicit Return, Multi-Line\n};\n\n(a) =\u003e a; // Implicit Return, Single-Line\n\n(a) =\u003e a; // Implicit Return, Multi-Line\n\n(a, b) =\u003e a + b; // Multiple Parameters (Parentheses Required)\n```\n\n2. Return Behavior\n\n- **Normal Functions**: Always require the `return` keyword to return a value.\n- **Arrow Functions**: Allow implicit returns where the `return` keyword can be omitted for single-line expressions.\n\n```javascript\n// Normal Function\nfunction multiply(a, b) {\n  return a * b; // Explicit Return\n}\n\n// Arrow Function\nconst multiply = (a, b) =\u003e a * b; // Implicit Return\n```\n\n3. Arguments Object\n\n- **Normal Functions**: Have access to the `arguments` object, which contains the arguments passed to the function.\n- **Arrow Functions**: Do not have their own `arguments` object.\n\n```javascript\n// Normal Function\nfunction printArguments() {\n  console.log(arguments);\n}\nprintArguments(1, 2, 3); // Output: [1, 2, 3]\n\n// Arrow Function\nconst printArguments = () =\u003e {\n  console.log(arguments);\n};\nprintArguments(1, 2, 3); // Error: 'arguments' is not defined\n```\n\n4. `this` Binding\n\n- **Normal Functions**: Create their own `this` context, which depends on how the function is called.\n- **Arrow Functions**: Do not create their own `this` context; they inherit `this` from the surrounding scope.\n\n```javascript\n// Normal Function\nconst obj1 = {\n  name: \"Normal Function\",\n  print: function () {\n    console.log(this);\n  },\n};\nobj1.print(); // Logs the obj1 object\n\n// Arrow Function\nconst obj2 = {\n  name: \"Arrow Function\",\n  print: () =\u003e {\n    console.log(this);\n  },\n};\nobj2.print(); // Logs the global 'window' object (or 'undefined' in strict mode)\n```\n\n5. Constructors\n\n- **Normal Functions**: Can be used as constructors with the `new` keyword.\n- **Arrow Functions**: Cannot be used as constructors and will throw an error if used with `new`.\n\n```javascript\n// Normal Function as Constructor\nfunction Person(name) {\n  this.name = name;\n}\nconst person1 = new Person(\"Abdul Ahad\"); // Works\n\n// Arrow Function as Constructor\nconst Person = (name) =\u003e {\n  this.name = name;\n};\nconst person2 = new Person(\"Abdul Ahad\"); // Error: Person is not a constructor\n```\n\n6. Hoisting\n\n- **Normal Functions**: Can be declared and are hoisted to the top of their scope.\n- **Arrow Functions**: Cannot be accessed before initialization.\n\n```javascript\n// Normal Function\nconsole.log(add(2, 3)); // Works\nfunction add(a, b) {\n  return a + b;\n}\n\n// Arrow Function\nconsole.log(subtract(5, 2)); // Error: Cannot access 'subtract' before initialization\nconst subtract = (a, b) =\u003e a - b;\n```\n\n7. Declaration\n\n- **Normal Functions**: Can be declared using the `function` keyword.\n- **Arrow Functions**: Must always be assigned to a variable or constant.\n\n```javascript\n// Normal Function Declaration\nfunction greet() {\n  console.log(\"Hello!\");\n}\n\n// Arrow Function Assignment\nconst greet = () =\u003e {\n  console.log(\"Hello!\");\n};\n```\n\n| **Feature**          | **Normal Function**          | **Arrow Function**              |\n| -------------------- | ---------------------------- | ------------------------------- |\n| **Syntax**           | `function add(a, b) { ... }` | `const add = (a, b) =\u003e { ... }` |\n| **Return**           | Explicit Return Required     | Allows Implicit Return          |\n| **arguments Object** | Available                    | Not Available                   |\n| **this Binding**     | Creates Own `this`           | Inherits `this`                 |\n| **Constructor**      | Can Be Used                  | Cannot Be Used                  |\n| **Hoisting**         | Fully Hoisted                | Not Hoisted                     |\n| **Declaration**      | Using function keyword       | Must Be Assigned to Variable    |\n\n---\n\n## ❓ What is the Difference Between Function Expression and Anonymous Function?\n\n1. Function Expression\n   A **Function Expression** is when you define a function and store it in a variable. You can use the variable to call the function later.\n\n- The function expression can be:\n- **Anonymous** (no name).\n- **Named** (optional name).\n- It’s **not hoisted**, so you cannot use it before defining it.\n\n```javascript\n// Function stored in a variable\nlet add = function (a, b) {\n  return a + b;\n};\nconsole.log(add(10, 20)); // Output: 30\n\n// Function with a name stored in a variable\nconst multiply = function multiplyNumbers(a, b) {\n  return a * b;\n};\nconsole.log(multiply(10, 20)); // Output: 200\n```\n\n2. Anonymous Function\n   An **Anonymous Function** is a function without a name. It’s commonly used for one-time tasks, like in event handlers or `setTimeout`.\n\n- Typically used when you don’t need to reuse the function elsewhere.\n\n```javascript\nsetTimeout(function () {\n  console.log(\"Hello, I am an Anonymous Function!\");\n}, 1000);\n```\n\n3. Function Declaration\n   A **Function Declaration** is the traditional way to define reusable functions in JavaScript.\n\n- Starts with the function keyword.\n- Always has a name.\n- Hoisted: You can call the function even before it’s defined in the code.\n\n```javascript\nfunction addNumbers(a, b) {\n  return a + b;\n}\nconsole.log(addNumbers(5, 15)); // Output: 20\n```\n\n| Feature         | Function Expression | Anonymous Function | Function Declaration |\n| --------------- | ------------------- | ------------------ | -------------------- |\n| **Name**        | Optional            | Not present        | Always present       |\n| **Hoisting**    | No                  | No                 | Yes                  |\n| **Reusability** | Yes                 | No                 | Yes                  |\n\n---\n\n## ❓ What is a First-Class Function?\n\nIn JavaScript, functions are treated like values. You can:\n\n- Store them in variables.\n- Pass them as arguments to other functions.\n- Return them from other functions.\n- Store them in objects and arrays.\n\nThis concept is called **First-Class Functions**.\n\n1. Store a Function in a Variable\n   You can define a function and save it in a variable.\n\n```javascript\nlet add = function (a, b) {\n  return a + b;\n};\nconsole.log(add(10, 20)); // Output: 30\n```\n\n2. Pass a Function as an Argument\n   Functions can be passed as arguments to other functions. This allows for dynamic behavior based on the function passed.\n\n```javascript\nfunction sayHello() {\n  return \"Hello, \";\n}\nfunction executeFunction(callback) {\n  return callback() + \"World\";\n}\nconsole.log(executeFunction(sayHello)); // Output: Hello, World\n```\n\n3. Return a Function from Another Function\n   Functions can generate and return other functions, allowing for closures and reusable logic.\n\n```javascript\nfunction outerFunction() {\n  function innerFunction() {\n    return \"Hello, World\";\n  }\n  return innerFunction;\n}\nlet inner = outerFunction();\nconsole.log(inner()); // Output: Hello, World\n```\n\n4. Store Functions in Arrays and Objects\n   Functions can be stored as elements in arrays or as properties in objects. This makes it easy to organize and execute specific tasks.\n\n```javascript\nconst operations = [\n  function (a, b) {\n    return a + b;\n  }, // Addition\n  function (a, b) {\n    return a * b;\n  }, // Multiplication\n];\n\nconsole.log(operations[0](2, 3)); // Output: 5\nconsole.log(operations[1](2, 3)); // Output: 6\n```\n\n```javascript\nconst calculator = {\n  add: function (a, b) {\n    return a + b;\n  },\n  subtract: function (a, b) {\n    return a - b;\n  },\n};\n\nconsole.log(calculator.add(3, 2)); // Output: 5\nconsole.log(calculator.subtract(3, 2)); // Output: 1\n```\n\n\u003e First-Class Functions = Functions that can be treated like values\n\n---\n\n## ❓ What is a Callback Function?\n\n\u003e A callback function is a function passed as an argument to another function that gets executed later, often after some operation completes.\n\nUse Cases:\n\n- Asynchronous operations (setTimeout, API calls, DOM events)\n- Functional programming patterns\n\n```js\n// Simple Callback Example\nfunction greet(name, callback) {\n  console.log(\"Hi \" + name);\n  callback();\n}\n\nfunction askQuestion() {\n  console.log(\"How are you?\");\n}\n\ngreet(\"Ahad\", askQuestion);\n// Output:\n// Hi Ahad\n// How are you?\n```\n\n```js\n// setTimeout with Callback\nsetTimeout(function () {\n  console.log(\"Executed after 2 seconds\");\n}, 2000);\n```\n\n```js\n// Array Method Example\nconst nums = [1, 2, 3];\nnums.forEach(function (num) {\n  console.log(num * 2); // 2, 4, 6\n});\n```\n\n```js\n// Custom Callback Logic\nfunction doSomething(callback) {\n  console.log(\"Doing something...\");\n  callback(\"Task done\");\n}\n\ndoSomething(function (msg) {\n  console.log(msg); // Task done\n});\n```\n\n### Why Use Callback Functions?\n\n- To handle asynchronous logic\n- To customize behavior dynamically\n- To keep code flexible and modular\n\n\u003e A callback lets one function defer control to another function.\n\n---\n\n## ❓ What is a Pure Function?\n\nA **pure function**:\n\n- Depends only on its **input arguments**\n- Has **no side effects**\n- Always returns the **same output** for the same input\n\n```js\n // (Pure):\nfunction add(a, b) {\n  return a + b;\n}\n\n// ❌ Not Pure:\nlet total = 0;\nfunction addToTotal(a) {\n  total += a; // modifies external state (side effect)\n}\n```\n\n---\n\n## ❓ What is IIFE (Immediately Invoked Function Expression)?\n\nAn **IIFE (Immediately Invoked Function Expression)** is a JavaScript function that runs **immediately after it is defined**.\n\nIt’s a function that executes itself.\n\n```js\n(function () {\n  // code here\n})();\n```\n\n### Types of IIFE\n\n1. Anonymous Function IIFE\n   An IIFE without a name that runs immediately.\n\n   ```js\n   (function () {\n     console.log(\"Hello, I am an Anonymous function IIFE!\");\n   })();\n   ```\n\n   **Arrow function version:**\n\n   ```js\n   (() =\u003e console.log(\"Hello, I am an Anonymous function IIFE!\"))(); // Alternatively, using an arrow function\n   ```\n\n2. Named Function IIFE\n   An IIFE that includes a function name.\n\n   ```js\n   (function welcome() {\n     console.log(\"Hello, I am a Named function IIFE!\");\n   })();\n   ```\n\n   **Passing parameters:**\n\n   ```js\n   (function add(a, b) {\n     console.log(a + b);\n   })(2, 3); // Output: 5\n   ```\n\n### Benefits of Using IIFE\n\n1. Data Privacy\n   IIFE helps ensure data privacy by making variables declared inside the IIFE inaccessible from the outside world. This avoids polluting the global scope.\n\n   ```javascript\n   (function () {\n     var message = \"IIFE\";\n     console.log(message);\n   })();\n   console.log(message); // Error: message is not defined\n   ```\n\n2. Return Value from IIFE\n   IIFE can be used to immediately return values from a function.\n\n   ```javascript\n   var value = (() =\u003e 100)();\n   console.log(value); // Output: 100\n   ```\n\n3. Asynchronous IIFE\n   IIFE allows you to execute `async/await` operations immediately.\n\n   ```javascript\n   const data = (async () =\u003e await fetch(url))();\n   ```\n\n### 🤔 How to Invoke IIFE Without Extra Parentheses?\n\nImmediately Invoked Function Expressions (IIFE) usually require parentheses to wrap the function. However, you can avoid using extra parentheses by utilizing the `void` operator, which discards the result of the expression.\n\n```javascript\n// Using void to Avoid Extra Parentheses\nvoid (function (dt) {\n  console.log(dt.toLocaleTimeString());\n})(new Date());\n```\n\n---\n\n## ❓ What is Currying? And Curied Function?\n\n\u003e Think of currying as a **type of closure**.\n\n**Currying** is a functional programming technique in JavaScript where a function with multiple arguments is transformed into a series of functions that each take **one argument at a time**.\n\nInstead of:\n\n```js\nf(a, b, c);\n```\n\nYou write:\n\n```js\nf(a)(b)(c);\n```\n\n### Example: Normal vs Curried\n\n❌ Normal Function\n\n```js\nfunction add(a, b) {\n  return a + b;\n}\n\nconsole.log(add(2, 3)); // Output: 5\n```\n\n✅ Curried Version\n\n```js\nfunction add(a) {\n  return function (b) {\n    return a + b;\n  };\n}\n\nconsole.log(add(2)(3)); // Output: 5\n```\n\n- The first function takes `a`\n  - Then returns another function that takes `b`\n  - Finally, returns the result of `a + b`\n\n```js\n// Real-World Example: Reusable Greetings\nfunction greet(greeting) {\n  return function (name) {\n    return `${greeting}, ${name}!`;\n  };\n}\n\nconst sayHi = greet(\"Hi\");\nconsole.log(sayHi(\"Ahad\")); // Hi, Ahad!\nconsole.log(sayHi(\"Zaid\")); // Hi, Zaid!\n```\n\n\u003e Reusability: You can create multiple greeting variations from the same curried base function.\n\n```js\n// Multiple-Level Currying\nfunction sum(a) {\n  return function (b) {\n    return function (c) {\n      console.log(a, b, c);\n      return a + b + c;\n    };\n  };\n}\nconsole.log(sum(1)(2)(3)); // Output: 6\n```\n\n✅ Arrow Function Version\n\n```js\nconst add = (a) =\u003e (b) =\u003e (c) =\u003e a + b + c;\nconsole.log(add(1)(2)(3)); // Output: 6\n```\n\n```js\n// Logging with Currying\nlet log = (time) =\u003e (type) =\u003e (msg) =\u003e\n  `At ${time.toLocaleString()}: severity ${type} =\u003e ${msg}`;\n\nconsole.log(log(new Date())(\"error\")(\"power not sufficient\"));\n\nlet logNow = log(new Date());\nconsole.log(logNow(\"warning\")(\"temp high\"));\n\nlet logErrorNow = log(new Date())(\"error\");\nconsole.log(logErrorNow(\"unknown error\"));\n```\n\n```js\n// Currying with Operation Type\nfunction op(operation) {\n  return function (a) {\n    return function (b) {\n      return operation === \"add\" ? a + b : a - b;\n    };\n  };\n}\n\nconst add3 = op(\"add\")(3);\nconst sub3 = op(\"sub\")(3);\nconst add = op(\"add\");\n\nconsole.log(add3(6)); // 9\nconsole.log(sub3(6)); // -3\nconsole.log(add(1)(2)); // 3\n```\n\n\u003e **Important Note:**\n\u003e Currying does not mean calling multiple parameters normally.\n\n```js\n// ❌ This is NOT currying\nfunction fakeCurrying(a, b, c) {\n  return a + b + c;\n}\n```\n\n\u003e Currying means returning functions for each parameter.\n\n### Infinite Currying\n- Keep returning functions until a call is made with **no argument**, at which point the final result is returned.\n\n```js\nfunction add(a) {\n  return function(b) {\n    if (b !== undefined) {\n      return add(a + b);\n    }\n    return a;\n  };\n}\n```\n```js\nadd(2)(3)(4)(5)(); // Output: 14\n```\n\n#### One Liner Version\n```js\nconst add = a =\u003e b =\u003e b !== undefined ? add(a + b) : a;\n```\n\n---\n\n## ❓ What are Functions Behaviour in JavaScript?\n\n### 1. Functions are First-Class Objects\n\n- In JavaScript, functions are **objects**.\n- This means they can:\n  - Be stored in variables\n  - Be passed as arguments\n  - Be returned from other functions\n  - Have **properties** like any object\n\n```js\nfunction sayHi(greet) {\n  return greet;\n}\n\nsayHi.name; // \"sayHi\" ➡️ function name\nsayHi.length; // 1 ➡️ number of parameters\n\nsayHi.count = 0; // You can add custom properties!\nsayHi.count++;\nconsole.log(sayHi.count); // 1\n```\n\n### 2. Function Declaration vs Function Expression\n\n| Type                 | Hoisted | Callable Before Declaration |\n| -------------------- | ------- | --------------------------- |\n| Function Declaration | ✅ Yes  | ✅ Yes                      |\n| Function Expression  | ❌ No   | ❌ No                       |\n\n```js\nsayHi(); // ✅ Works\nfunction sayHi() {\n  return \"Hi!\";\n}\n\nsayHello(); // ❌ ReferenceError\nlet sayHello = function () {\n  return \"Hello!\";\n};\n```\n\n### 3. Constructor Functions\n\nFunctions can be called with `new` to create custom objects.\n\n```js\nfunction Person(name) {\n  this.name = name;\n}\n\nconst p = new Person(\"Abdul Ahad\");\nconsole.log(p.name); // \"Abdul Ahad\"\n```\n\n### 4. Named Function Expression (NFE)\n\nHelpful for self-reference even if the variable is reassigned.\n\n```js\nlet sayHello = function fx(user) {\n  if (user) return \"Hello \" + user;\n  else return fx(\"Anonymous\"); // Recursive call using name fx\n};\n\nlet sayHi = sayHello;\nsayHello = null;\n\nconsole.log(sayHi()); // \"Hello Anonymous\"\n```\n\n### 5. Decorators (Function Wrappers)\n\nA design pattern to enhance or modify a function without changing its original code.\n\n### Memoization Example\n\n```js\nfunction heavy(x) {\n  console.log(x + \":heavy\");\n  return x + \":heavy\";\n}\n\nfunction memoized(fx) {\n  let map = new Map();\n  return function (x) {\n    if (map.has(x)) return map.get(x);\n    let val = fx(x);\n    map.set(x, val);\n    return val;\n  };\n}\n\nconst memoHeavy = memoized(heavy);\n\nmemoHeavy(2); // logs and returns\nmemoHeavy(2); // returns from cache\n```\n\n\u003e Use case: Caching expensive operations like API calls, Fibonacci, etc.\n\n### 🧨 Problem: `this` is lost in memoization\n\n```js\nlet task = {\n  name: \"demo\",\n  heavy(x) {\n    console.log(x + \":heavy:\" + this.name);\n    return x + \":heavy:\" + this.name;\n  },\n};\n\ntask.memoizedHeavy = memoized(task.heavy);\ntask.memoizedHeavy(1); // ❌ undefined — `this` is lost\n```\n\n### ❓ Why does it fail?\n\n- In **non-strict mode**, `this` defaults to `window` (global).\n- In **strict mode**, `this` is `undefined`.\n- `task.heavy` loses its context when passed as a callback.\n\n### Solution: Use `.call(this, x)` inside wrapper\n\n```js\nfunction memoized(fx) {\n  let map = new Map();\n  return function (x) {\n    if (map.has(x)) return map.get(x);\n    let val = fx.call(this, x); // ✅ Preserve original `this`\n    map.set(x, val);\n    return val;\n  };\n}\n```\n\nNow:\n\n```js\ntask.memoizedHeavy = memoized(task.heavy);\ntask.memoizedHeavy(1); // ✅ Works — \"1:heavy:demo\"\n```\n\n---\n\n## ❓ What is Debounce and Throttle?\n\nThese are **performance optimization patterns**, especially useful for handling **frequent events** like:\n\n- Typing (`keyup`)\n- Scrolling\n- Resizing\n- Mouse movement\n\nBoth are types of **decorators** (wrappers) that **control the rate** of function execution.\n\n### 🕐 1. **Debounce**\n\n\u003e ✅ Only run the function after the user has stopped triggering it for a fixed time.\n\u003e A technique to delay the execution of a function until a specified time has passed without calling it again.\n\n### Real-World Analogy:\n\n- Typing in a search box...\n- You **don’t want to search** on every key press — only after the user **pauses** typing (say, for 1 second).\n\n### How It Works:\n\n- Each call **resets** the timer.\n- Only the **last call** after a pause is executed.\n\n```js\nfunction debounce(fx, time) {\n  let id = null;\n\n  return function (x) {\n    if (id) clearTimeout(id); // Cancel previous timer\n    id = setTimeout(() =\u003e {\n      fx(x); // Only call after pause\n      id = null;\n    }, time);\n  };\n}\n```\n\n```js\nlet count = 1;\nfunction showCount() {\n  console.log(count++);\n}\n\nconst showCountD = debounce(showCount, 2000);\n\nsetTimeout(showCountD, 1000);\nsetTimeout(showCountD, 1500);\nsetTimeout(showCountD, 2000);\nsetTimeout(showCountD, 2500);\nsetTimeout(showCountD, 5000); // ✅ Only final call runs after 2s pause\n```\n\n### DOM Example (Live Search Input):\n\n```\nconst el = document.getElementById('text1');\nconst logo = document.getElementById('text-output1');\n\nel.addEventListener(\n  'keyup',\n  debounce(function (e) {\n    logo.innerText = e.target.value;\n  }, 1000)\n);\n```\n\n```html\n\u003cinput type=\"text\" id=\"text1\" /\u003e\n\u003cp id=\"text-output1\"\u003e\u003c/p\u003e\n```\n\n### Real-Life Analogy:\n\n\u003e 👧 A kid tells her mom: \"Give me chocolate!\"\n\u003e\n\u003e 🧓 Mom says: _\"Be quiet for 10 minutes, then I will!\"_\n\u003e\n\u003e ❌ If the kid speaks again — the timer resets.\n\u003e\n\u003e ✅ Only if quiet for 10 mins straight, she gets chocolate.\n\n| Feature       | Debounce                                     |\n| ------------- | -------------------------------------------- |\n| Trigger logic | After inactivity pause ⏸️                    |\n| Use case      | Search inputs, form validations, live typing |\n| Key behavior  | Cancels previous calls, runs only the last   |\n\n### 🚦 2. **Throttle**\n\n\u003e Run the function at most once in a specified time window — even if it’s triggered many times.\n\n\u003e A technique to limit function execution to once per given time period, even if called many times.\n\n### Real-World Analogy:\n\nYou are scrolling rapidly, but you only want to run a function **every 100ms** — no matter how fast the user rolls.\n\n### How It Works:\n\n- Once triggered, it **ignores repeated calls** until time expires.\n\n```js\nfunction throttle(fx, time) {\n  let id = null;\n  let arg = [];\n\n  return function (x) {\n    arg[0] = x;\n    if (!id) {\n      id = setTimeout(() =\u003e {\n        fx(arg[0]);\n        id = null; // Reset for next window\n      }, time);\n    }\n  };\n}\n```\n\n```js\nlet count = 1;\nfunction showCount() {\n  console.log(count++);\n}\n\nconst showCountT = throttle(showCount, 2000);\n\nsetTimeout(showCountT, 1000);\nsetTimeout(showCountT, 1500);\nsetTimeout(showCountT, 2000);\nsetTimeout(showCountT, 2500);\nsetTimeout(showCountT, 5000); // ✅ Runs once every 2 seconds\n```\n\n### DOM Example (Scroll Event):\n\n```\nfunction sayHi() {\n  console.log(\"hi\");\n}\n\ndocument.addEventListener('scroll', throttle(sayHi, 1000));\n```\n\n### Real-Life Analogy:\n\n\u003e 👧 A kid tells her mom: \"I want food!\"\n\u003e\n\u003e 🧓 Mom says: _\"Okay, but you'll only get it **once every 10 minutes**, no matter how many times you ask.\"_\n\u003e\n\u003e 🕐 Kid keeps asking at 3 min, 5 min, 8 min...\n\u003e\n\u003e ❌ Mom ignores all in-between requests\n\u003e\n\u003e ✅ At the **10-minute mark**, she gives food — **only once**\n\u003e\n\u003e Then timer starts again...\n\n🗣️ **Meaning:**\n\nEven if an event happens **repeatedly**, it will **only be handled at regular intervals**, not every time it fires.\n\n| Feature       | Throttle                                   |\n| ------------- | ------------------------------------------ |\n| Trigger logic | At most once per time window ⏱️            |\n| Use case      | Scroll, resize, drag, mousemove            |\n| Key behavior  | Ignores repeated triggers during wait time |\n\n| Concept         | Real-Life Analogy                                                                     |\n| --------------- | ------------------------------------------------------------------------------------- |\n| **Debounce** ⏳ | _\"Stay quiet for 10 minutes, then you'll get chocolate. If you speak, timer resets.\"_ |\n| **Throttle** 🚦 | _\"Ask for food all you want, you'll only get it once every 10 minutes.\"_              |\n\n### Debounce vs Throttle — Quick Comparison\n\n| Feature         | Debounce 🧯              | Throttle 🚦               |\n| --------------- | ------------------------ | ------------------------- |\n| Triggered when  | After inactivity timeout | Once per fixed interval   |\n| Use case        | Typing, search inputs    | Scroll, resize, mousemove |\n| Cancel previous | ✅ Yes                   | ❌ No                     |\n| Skips calls?    | ✅ All before pause      | ✅ All during interval    |\n\n### Bonus: Arrow Function Differences\n\n| Feature               | Arrow Functions (`=\u003e`)     | Normal Functions |\n| --------------------- | -------------------------- | ---------------- |\n| `this` binding        | ❌ Lexical (no own `this`) | ✅ Own `this`    |\n| `arguments` object    | ❌ Not available           | ✅ Available     |\n| Used as constructor?  | ❌ No (`new` not allowed)  | ✅ Yes           |\n| Has `name` \u0026 `length` | ✅ Yes                     | ✅ Yes           |\n\n---\n\n## ❓ What are Iterables \u0026 Generators in JavaScript?\n\n### What are Iterables?\n\n\u003e Objects that can be looped through one by one using `for...of` or the spread `...` operator.\n\n`OR`\n\n\u003e An object is **iterable** if it implements the **`Symbol.iterator()`** method that returns an **iterator object**.\n\n**Built-in Iterables:**\n\n- Arrays ✅\n- Strings ✅\n- Maps \u0026 Sets ✅\n\n### What is an Iterator?\n\n- An object with a `.next()` method.\n- `.next()` returns an object:\n\n  ```js\n  { value: any, done: boolean }\n  ```\n\n  - `done: true` means iteration finished.\n\n  ```js\n  const iterator = [10, 20][Symbol.iterator]();\n\n  console.log(iterator.next()); // { value: 10, done: false }\n  console.log(iterator.next()); // { value: 20, done: false }\n  console.log(iterator.next()); // { value: undefined, done: true }\n  ```\n\n````\n\n### How to Create a Custom Iterable?\n\n- Implement `[Symbol.iterator]` method returning an iterator.\n- Iterator has a `.next()` method returning `{ value, done }`.\n\n```js\nconst range = {\n  start: 1,\n  end: 3,\n  [Symbol.iterator]() {\n    let current = this.start;\n    const end = this.end;\n    return {\n      next() {\n        if (current \u003c= end) {\n          return { value: current++, done: false };\n        } else {\n          return { done: true };\n        }\n      }\n    };\n  }\n};\n\nfor (const num of range) {\n  console.log(num); // 1, 2, 3\n}\n````\n\nWhat is a Generator?\n\n- A special function that can pause (`yield`) and resume.\n- Implements iterable and iterator protocols automatically.\n- Simplifies iterator creation.\n\nSyntax and Example:\n\n```js\nfunction* genFunc() {\n  yield 1;\n  yield 2;\n  yield 3;\n}\nconst gen = genFunc();\n\nconsole.log(gen.next()); // { value: 1, done: false }\nconsole.log(gen.next()); // { value: 2, done: false }\nconsole.log(gen.next()); // { value: 3, done: false }\nconsole.log(gen.next()); // { value: undefined, done: true }\n```\n\n### Why Use Generators?\n\n- Lazy evaluation: produce values on demand.\n- Can create infinite sequences safely.\n- Useful for asynchronous flows.\n- Cleaner syntax for iterators.\n\n### Can Generators Create Infinite Sequences?\n\nYes, using loops inside the generator:\n\n```js\nfunction* infiniteCounter() {\n  let i = 0;\n  while (true) {\n    yield i++;\n  }\n}\nconst counter = infiniteCounter();\n\nconsole.log(counter.next().value); // 0\nconsole.log(counter.next().value); // 1\n```\n\n\u003e ⚠️ Use carefully to avoid infinite loops.\n\n### Using Generators with for...of and Spread\n\nGenerators are iterable:\n\n```js\nfunction* nums() {\n  yield 1;\n  yield 2;\n  yield 3;\n}\n\nconsole.log([...nums()]); // [1, 2, 3]\n```\n\n### Generator Composition (yield\\*)\n\nUse `yield*` to delegate to another generator:\n\n```js\nfunction* range(start, end) {\n  for (let i = start; i \u003c= end; i++) yield i;\n}\n\nfunction* composed() {\n  yield* range(1, 3);\n  yield* range(100, 102);\n}\n\nconsole.log([...composed()]); // [1, 2, 3, 100, 101, 102]\n```\n\n### Passing Values to Generators\n\nYou can send values back into a generator via `.next(value)`:\n\n```js\nfunction* gen() {\n  const val = yield \"first yield\";\n  console.log(\"Received:\", val);\n}\nconst g = gen();\n\ng.next(); // Start generator, yields 'first yield'\ng.next(\"Hello\"); // Logs 'Received: Hello'\n```\n\n| Feature                        | Iterable                    | Iterator             | Generator                |\n| ------------------------------ | --------------------------- | -------------------- | ------------------------ |\n| Implements `Symbol.iterator()` | Yes (returns iterator)      | Optional             | Yes (built-in)           |\n| Has `.next()` method           | No                          | Yes                  | Yes                      |\n| Can be looped by `for...of`    | Yes                         | No                   | Yes                      |\n| Purpose                        | Provides iterable interface | Steps through values | Creates iterators easily |\n| Infinite sequence              | Usually No                  | Yes (manual control) | Yes                      |\n\n---\n\n## ❓ What is an Object in JavaScript?\n\nAn **object** in JavaScript is a variable that can store **multiple values** as **key-value pairs**.\n\nObjects are great for grouping related data and behavior.\n\n```js\nlet person = {\n  name: \"Ahad Ali\",\n  age: 30,\n  city: \"New York\",\n};\n\nconsole.log(person.name); // Output: Ahad Ali\n```\n\n- Properties store data.\n- Methods are functions stored in properties.\n- Keys are strings (or Symbols), values can be any data type.\n\n### Object References \u0026 Nesting\n\n**Object References**\n\n```js\nlet person = { name: \"Ahad Ali\" };\nlet human = person;\n\nhuman.name = \"Abdul Ahad\";\nconsole.log(person.name); // Abdul Ahad\n```\n\n- Objects are assigned by **reference**, not copied.\n- Changing one reference affects the other.\n\n**Nesting of Objects**\n\nObjects can hold other objects:\n\n```js\nlet person = {\n  name: \"Ahad Ali\",\n  address: { city: \"Delhi\", state: \"Delhi\" },\n};\n\nconsole.log(person.address.city); // Delhi\n```\n\n---\n\n## ❓ What is the Difference between Deep Copy and Shallow Copy in JavaScript?\n\n### Shallow Copy\n\nA **shallow copy** duplicates only the top-level structure of an object or array.\nIt **does not clone nested objects or arrays**, meaning they are still **shared by reference**.\n\n- ✅ Top-level properties copied\n- ❌ Nested objects remain linked (reference)\n\n```js\n// Reference Copy Example\nlet person = { name: \"Abdul Ahad\", address: { city: \"Delhi\" } };\nlet newPerson = { ...person };\n\nnewPerson.address.city = \"Mumbai\";\nconsole.log(person.address.city); // Mumbai ❗ (affected)\n```\n\n```js\n// Primitive Copy Example\nnewPerson.name = \"Ahad Ali\";\nconsole.log(person.name); // Abdul Ahad ✅ (not affected)\n```\n\n| Type      | Copied As    | Affects Original? |\n| --------- | ------------ | ----------------- |\n| Primitive | By Value     | ❌ No             |\n| Object    | By Reference | ✅ Yes            |\n\n```js\n//  Shallow Copy in Action\nconst original = { name: \"Mudassir\", details: { age: 25, city: \"New York\" } };\n\n// Shallow copy using spread operator\nconst shallowCopy = { ...original };\n\nshallowCopy.name = \"Ahsan\";\nshallowCopy.details.age = 30;\n\nconsole.log(original.details.age); // 30 ❗\nconsole.log(shallowCopy.details.age); // 30\n```\n\n### What is Deep Copy?\n\nA **deep copy** creates a **fully independent copy** of the object, including **all nested objects and arrays**.\n\n- ✅ Changes in the copy **do not affect** the original\n- ✅ Useful for safely working with complex data structures\n\n### 1. Deep Copy Using `JSON.stringify()` + `JSON.parse()`\n\n```js\nlet person = {\n  name: \"Abdul Ahad\",\n  address: { city: \"Delhi\" },\n};\n\nlet deepCopy = JSON.parse(JSON.stringify(person));\n```\n\n⚠️ Limitations:\n\n- ❌ Doesn’t copy `undefined`, `functions`, `Date`, `Map`, `Set`, circular refs\n\n### 2. Deep Copy Using `structuredClone()` (Modern Browsers)\n\n```js\nlet person = {\n  name: \"Abdul Ahad\",\n  address: { city: \"Delhi\" },\n};\n\nlet deep = structuredClone(person);\n```\n\n```js\n// Deep Copy in Action\nconst original = { name: \"Alice\", details: { age: 25, city: \"New York\" } };\n\n// Deep copy using JSON methods\nconst deepCopy = JSON.parse(JSON.stringify(original));\n\ndeepCopy.name = \"Ahsan\";\ndeepCopy.details.age = 30;\n\nconsole.log(original.details.age); // 25 ✅\nconsole.log(deepCopy.details.age); // 30\n```\n\n| Feature                 | Shallow Copy                  | Deep Copy                                                |\n| ----------------------- | ----------------------------- | -------------------------------------------------------- |\n| What it copies          | Only top-level properties     | All levels (including nested objects)                    |\n| Nested references       | ❌ Still point to original    | ✅ Completely independent                                |\n| Affects original?       | ✅ Yes (for nested data)      | ❌ No                                                    |\n| Copy method example     | `const copy = { ...obj }`     | `JSON.parse(JSON.stringify(obj))` or `structuredClone()` |\n| Supports functions?     | ✅ Yes                        | ❌ No (if using JSON methods)                            |\n| Supports circular refs? | ✅ Yes (manual or modern API) | ✅ Yes (`structuredClone()`) only                        |\n\n---\n\n## ❕ Bonus Questions\n\n### Delete keyword in functions\n\n```js\nconst func = (function (a) {\n  delete a;\n  return a;\n})(5);\nconsole.log(func); // 5\n```\n\n✅ **Explanation**: `delete` only removes properties from **objects**. `a` is a local function argument (not an object property), so `delete a` does nothing.\n\n### Delete property from object\n\n```js\nconst user = {\n  name: \"Ahad Ali\",\n  age: 24,\n  \"like this video\": true,\n};\ndelete user[\"like this video\"];\nconsole.log(user);\n```\n\n✅ **Output**:\n\n```js\n{ name: 'Ahad Ali', age: 24 }\n```\n\n✅ **Explanation**: `delete` works on object properties. This successfully removes the dynamic key.\n\n### Dynamic object keys\n\n```js\nconst property = \"firstName\";\nconst name = \"Ahad Ali\";\nconst user = {\n  [property]: name,\n};\nconsole.log(user.firstName); // \"Ahad Ali\"\n```\n\n✅ **Explanation**: Computed property names using square brackets allow dynamic key assignment.\n\n### Looping over object keys\n\n```js\nconst user = {\n  name: \"Ahad Ali\",\n  age: 24,\n  isTotallyAwesome: true,\n};\nfor (key in user) {\n  console.log(user[key]);\n}\n```\n\n✅ **Output**:\n\n```js\nAhad Ali\n24\ntrue\n```\n\n✅ **Explanation**: `for...in` loops through enumerable properties.\n\n### Duplicate keys in object\n\n```js\nconst obj = {\n  a: \"one\",\n  b: \"two\",\n  a: \"three\",\n};\nconsole.log(obj);\n```\n\n✅ **Output**:\n\n```js\n{ a: 'three', b: 'two' }\n```\n\n✅ **Explanation**: Last key declaration wins. Earlier one is overwritten.\n\n### How to Multiply object values by 2?\n\n```js\nlet nums = {\n  a: 100,\n  b: 200,\n  title: \"My nums\",\n};\nfunction multiplyByTwo(obj) {\n  for (key in obj) {\n    if (typeof obj[key] === \"number\") {\n      obj[key] *= 2;\n    }\n  }\n}\nmultiplyByTwo(nums);\nconsole.log(nums);\n```\n\n✅ **Output**:\n\n```js\n{ a: 200, b: 400, title: 'My nums' }\n```\n\n✅ **Explanation**: Only numeric properties are modified.\n\n### Object keys as objects\n\n```js\nconst a = {};\nconst b = { key: \"b\" };\nconst c = { key: \"c\" };\na[b] = 123;\na[c] = 456;\nconsole.log(a[b]);\n```\n\n✅ **Output**:\n\n```js\n456;\n```\n\n✅ **Explanation**: Object keys are converted to strings. Both `b` and `c` become `\"[object Object]\"`, so the second assignment overrides the first.\n\n### JSON.stringify with selected keys\n\n```js\nconst settings = {\n  username: \"Ahad\",\n  level: 19,\n  health: 90,\n};\nconst data = JSON.stringify(settings, [\"level\", \"health\"]);\nconsole.log(data);\n```\n\n✅ **Output**:\n\n```js\n{\"level\":19,\"health\":90}\n```\n\n✅ **Explanation**: Second argument is a replacer array - it picks only specified keys.\n\n### Arrow function vs regular method in object\n\n```js\nconst shape = {\n  radius: 10,\n  diameter() {\n    return this.radius * 2;\n  },\n  perimeter: () =\u003e 2 * Math.PI * this.radius,\n};\nconsole.log(shape.diameter());\nconsole.log(shape.perimeter());\n```\n\n✅ **Output**:\n\n```js\n20;\nNaN;\n```\n\n✅ **Explanation**:\n\n- `diameter()` is a regular method — `this` refers to `shape`\n- `perimeter` is an arrow function — `this` does **not** refer to `shape`, but to outer scope\n\n### Destructuring nested object properties\n\n```js\nconst user = {\n  name: \"Ahad Ali\",\n  age: 24,\n  fullName: {\n    first: \"Ahad\",\n    last: \"Ali\",\n  },\n};\n\nconst {\n  fullName: { first },\n} = user;\nconsole.log(first); // \"Ahad\"\n```\n\n✅ **Explanation**: We're using **nested destructuring** to extract the `first` key from `fullName`. The variable `first` is available directly.\n\n### Object references and mutation\n\n```js\nlet c = { greeting: \"Hey!\" };\nlet d;\nd = c;\nc.greeting = \"Hello\";\nconsole.log(d.greeting); // \"Hello\"\n```\n\n✅ **Explanation**: `c` and `d` reference the same object in memory. Updating one reflects in the other.\n\n### Object comparison\n\n```js\nconsole.log({ a: 1 } == { a: 1 }); // false\nconsole.log({ a: 1 } === { a: 1 }); // false\n```\n\n✅ **Explanation**: Objects are only equal by **reference**, not by structure or value. These are two different object instances.\n\n### Reference kept in array after setting object to null\n\n```js\nlet person = { name: \"Abdul Ahad\" };\nconst members = [person];\nperson = null;\nconsole.log(members);\n```\n\n✅ **Output**:\n\n```js\n[{ name: \"Abdul Ahad\" }];\n```\n\n✅ **Explanation**: The array still holds a reference to the original object, even after `person = null`.\n\n### Object property set to null (not the object itself)\n\n```js\nlet person = { name: \"Abdul Ahad\" };\nconst members = [person];\nperson.name = null;\nconsole.log(members);\n```\n\n✅ **Output**:\n\n```js\n[{ name: null }];\n```\n\n✅ **Explanation**: Since both `person` and `members[0]` refer to the same object, changes in one reflect in the other.\n\n### Spread and default parameter reference behavior\n\n```js\nconst value = { number: 10 };\nconst multiply = (x = { ...value }) =\u003e {\n  console.log((x.number *= 2));\n};\n\nmultiply(); // 20\nmultiply(); // 20\nmultiply(value); // 20\nmultiply(value); // 40\n```\n\n✅ **Explanation**:\n\n- `{ ...value }` creates a **new copy** each time, so default calls don’t affect each other.\n- When `value` is passed directly, mutation affects the same object.\n\n### Object mutation vs reassignment\n\n```js\nfunction changeAgeAndReference(person) {\n  person.age = 25;\n  person = {\n    name: \"Abdul Ahad\",\n    age: 50,\n  };\n  return person;\n}\n\nconst personObj1 = {\n  name: \"Ahad Ali\",\n  age: 30,\n};\n\nconst personObj2 = changeAgeAndReference(personObj1);\nconsole.log(personObj1); // { name: 'Ahad Ali', age: 25 }\nconsole.log(personObj2); // { name: 'Abdul Ahad', age: 50 }\n```\n\n✅ **Explanation**:\n\n- `person.age = 25` mutates the original object\n- `person = {...}` creates a **new object**, not affecting the original\n\n---\n\n## ❓ What are Prototypes \u0026 Prototypal Inheritance in JavaScript?\n\n### What are Prototypes in JavaScript?\n\n\u003e Every object in JavaScript has a hidden link to another object called its prototype.\n\nIf JavaScript doesn’t find a property on an object, it **goes to its prototype** to look for it.\n\n### Real-Life Analogy\n\nImagine you're asking your younger brother for a pen.\n\n- Your brother is the object.\n- Dad is the prototype.\n- JS will go up the chain (to Dad) until it finds the pen (property).\n\n### What is Prototypal Inheritance?\n\nPrototypal inheritance allows one object to inherit properties and methods from another.\n\n- JavaScript uses **objects extending other objects**.\n\n```js\nlet animal = { eats: true };\nlet dog = { barks: true };\n\ndog.__proto__ = animal;\n\nconsole.log(dog.barks); // true\nconsole.log(dog.eats); // true (inherited from animal)\n```\n\n✅ `dog.__proto__`→ points to `animal`\n\n```js\n// Prototype Chain\nlet animal = {\n  eats: true,\n  walks: function () {\n    return \"walks\";\n  },\n};\n\nlet dog = { barks: true };\ndog.__proto__ = animal;\n\nlet myDog = { name: \"sifu\" };\nmyDog.__proto__ = dog;\n\nconsole.log(myDog.name); // sifu\nconsole.log(myDog.barks); // true\nconsole.log(myDog.walks()); // walks\n```\n\n- **Chain:** myDog → dog → animal → Object.prototype → null\n\n### ⚠️ proto vs [[Prototype]]\n\n**proto** is a getter/setter (not recommended)\n\n✅ Preferred:\n\n```js\nObject.getPrototypeOf(obj);\nObject.setPrototypeOf(obj, prototypeObj);\n```\n\n### Inherited Methods Behavior\n\n```js\nlet dog = { barks: true };\nlet animal = {\n  eats: true,\n  walks: () =\u003e \"walks\",\n};\n\ndog.__proto__ = animal;\n\nlet myDog = { name: \"sifu\" };\nmyDog.__proto__ = dog;\nmyDog.walks = () =\u003e \"walks slowly\";\n\nconsole.log(myDog.walks()); // walks slowly\nconsole.log(dog.walks()); // walks\n```\n\n### Property Lookup Rules\n\n- Check own property first\n- Then prototype\n- Then up the chain\n\n```js\nlet obj = { a: 1 };\nconsole.log(obj.a); // 1\nconsole.log(obj.toString()); // from Object.prototype\n```\n\n---\n\n## ❓ What are Polyfills and Transpilers in JavaScript?\n\nA **polyfill** is a piece of code that adds support for modern JavaScript features\nin **older browsers** that don’t support them yet.\n\n- Think of it like a **backup version** of a modern feature — written using older code\n  so that it can still work in older environments.\n\n- Polyfills are **custom implementations** of modern features.\n- They check if a feature exists — and if not, define it manually.\n- Most polyfills extend built-in objects like `Array`, `Object`, `Promise`, etc.\n\n### Common Polyfill Interview Tasks\n\n- `forEach()`\n- `map()`\n- `filter()`\n- `reduce()`\n- `bind()`\n\n### ✅ Implementing `forEach()` from scratch\n\n```js\nArray.prototype.myForEach = function (callback) {\n  for (var i = 0; i \u003c this.length; i++) {\n    callback(this[i], i, this); // currentValue, index, array\n  }\n};\n\nlet arr = [\"Moosetape\", \"BDFU\", \"Godzilla\"];\narr.myForEach((item) =\u003e console.log(item));\n```\n\n### ✅ Implementing map() from scratch\n\n```js\nArray.prototype.myMap = function (callback) {\n  var arr = [];\n  for (var i = 0; i \u003c this.length; i++) {\n    arr.push(callback(this[i], i, this));\n  }\n  return arr;\n};\n\nlet arr = [\"Moosetape\", \"BDFU\", \"Godzilla\"];\nconst result = arr.myMap((item) =\u003e item.toUpperCase());\nconsole.log(result); // [\"MOOSETAPE\", \"BDFU\", \"GODZILLA\"]\n```\n\n### ✅ Implementing filter() from scratch\n\n```\nArray.prototype.myFilter = function (callback, context) {\n  let arr = [];\n  for (var i = 0; i \u003c this.length; i++) {\n    if (callback.call(context, this[i], i, this)) {\n      arr.push(this[i]);\n    }\n  }\n  return arr;\n};\n\nlet albums = [\n  { name: \"Moosetape\", songs: 20 },\n  { name: \"BDFU\", songs: 7 },\n  { name: \"Godzilla\", songs: 11 },\n];\n\nlet result = albums.myFilter(function (album) {\n  return album.songs \u003e 10;\n});\n\nconsole.log(result); // [{ name: \"Moosetape\", songs: 20 }, { name: \"Godzilla\", songs: 11 }]\n```\n\n### ✅ Implementing reduce() from scratch\n\n```js\nArray.prototype.myReduce = function (callback, initialValue) {\n  let accumulator = initialValue === undefined ? undefined : initialValue;\n\n  for (var i = 0; i \u003c this.length; i++) {\n    if (accumulator !== undefined) {\n      accumulator = callback.call(undefined, accumulator, this[i], i, this);\n    } else {\n      accumulator = this[i];\n    }\n  }\n\n  return accumulator;\n};\n\nlet arr = [\"Moosetape\", \"BDFU\", \"Godzilla\"];\nlet result = arr.myReduce(function (a, b) {\n  return a + \" \" + b;\n}, \"Tape -\");\n\nconsole.log(result); // Tape - Moosetape BDFU Godzilla\n```\n\n### ✅ Implementing bind() from scratch\n\n```js\nlet name = {\n  first: \"Ahad \",\n  last: \"Ali\",\n};\n\nlet display = function () {\n  console.log(`${this.first} ${this.last}`);\n};\n\nFunction.prototype.myBind = function (...args) {\n  let obj = this; // original function (display)\n  return function () {\n    obj.call(args[0]);\n  };\n};\n\nlet displayMe = display.myBind(name);\ndisplayMe(); // Ahad Ali\n```\n\nA **transpiler** converts modern JavaScript (ES6+) into older JavaScript (ES5)\nfor compatibility with older browsers.\n\nCommon tools:\n- Babel\n- TypeScript\n\nUsed in most front-end frameworks like React, Vue, Angular, etc.\n\n---\n\n## ❓ What are Classes in JavaScript?\n\n\u003e A class is a cleaner, more familiar way to write code that uses prototypal inheritance in JavaScript.\n\nIt’s just **syntactic sugar** — a nicer way to do the same thing you were already doing using functions and prototypes — but it also adds **extra features** like:\n\n- `get` and `set` methods\n- non-enumerable methods\n- auto `strict mode`\n- better error handling\n\n### Old Way (Prototypes):\n\n```js\nfunction User(name) {\n  this.name = name;\n}\n\nUser.prototype.sayHi = function () {\n  return this.name;\n};\n\nlet user = new User(\"Ahad\");\nuser.sayHi(); // Ahad\n```\n\n### 🆕 New Way (Class):\n\n```js\nclass User {\n  constructor(name) {\n    this.name = name;\n  }\n\n  sayHi() {\n    return this.name;\n  }\n}\n\nlet user = new User(\"Ahad\");\nuser.sayHi(); // Ahad\n```\n\n- Both ways work the same under the hood: `sayHi` is placed in the prototype.\n\n### Class is always in 'strict mode'\n\n```js\n// In normal JS\nx = 5; // works\n\n// In class environment (strict mode)\nclass Something {\n  constructor() {\n    x = 5; // ❌ ReferenceError\n  }\n}\n```\n\n### Class Getter and Setter\n\n```js\nclass User {\n  constructor(first, last) {\n    this.first = first;\n    this.last = last;\n  }\n\n  get fullName() {\n    return this.first + \" \" + this.last;\n  }\n\n  set fullName(name) {\n    [this.first, this.last] = name.split(\" \");\n  }\n}\n\nlet user = new User(\"Ahad\", \"Ali\");\nconsole.log(user.fullName); // Ahad Ali\n\nuser.fullName = \"Abdul Ahad Cena\";\nconsole.log(user.first); // Abdul Ahad\nconsole.log(user.last); // Cena\n```\n\n\u003e ✅ Clean way to access derived/computed properties\n\n### `this` Problem in Classes\n\n```js\nclass Button {\n  constructor(value) {\n    this.value = value;\n  }\n\n  click() {\n    console.log(this.value);\n  }\n}\n\nlet button = new Button(\"Play\");\n\n// ❌ Problem\nsetTimeout(button.click, 1000); // undefined\n```\n\n#### ❓ Why this fails:\n\n- When passing button.click into `setTimeout`, the this context is lost.\n\n### 3 Ways to Fix the this Problem\n\n1. Arrow function:\n\n```js\nsetTimeout(() =\u003e button.click(), 1000);\n```\n\n2. Bind:\n\n```js\nsetTimeout(button.click.bind(button), 1000);\n```\n\n3. Use class field:\n\n```js\nclass Button {\n  constructor(value) {\n    this.value = value;\n  }\n\n  click = () =\u003e {\n    console.log(this.value);\n  };\n}\n\nlet button = new Button(\"Play\");\nsetTimeout(button.click, 1000); // ✅ Works\n```\n\n---\n\n## ❓ What is Inheritance and Static method and access specifier in JS?\n\nInheritance allows a class (Child) to inherit properties and methods from another class (Parent) using the `extends` keyword.\n\n\u003e JavaScript uses prototypal inheritance under the hood, but class syntax simplifies it.\n\n### Basic Class Inheritance\n\n```js\nclass Shape {\n  constructor(name) {\n    this.name = name;\n  }\n\n  displayShape() {\n    return \"Shape \" + this.name;\n  }\n}\n\nclass Rectangle extends Shape {}\n\nconst rect1 = new Rectangle(\"Rect 1\");\nconsole.log(rect1.displayShape()); // Shape Rect 1\n```\n\n- Even without a constructor in Rectangle, the parent constructor is called automatically.\n\n### Custom Constructor in Child Class\n\nIf the child class has its own constructor, you must call super() to initialize the parent:\n\n```js\nclass Rectangle extends Shape {\n  constructor(name, width, height) {\n    super(name); // Call parent constructor\n    this.width = width;\n    this.height = height;\n    this.area = width * height;\n  }\n}\n\nconst rect2 = new Rectangle(\"Rect 2\", 10, 20);\nconsole.log(rect2.area); // 200\n```\n\n- super() must be the first line in the child constructor.\n\n### Prototype Chain\n\nUnder the hood, inheritance creates this structure:\n\n```\nrect1 → Rectangle.prototype → Shape.prototype → Object.prototype\n\n```\n\n### Static Methods\n\nA **static method** belongs to the class itself, not its instances.\n\n```js\nclass Shape {\n  constructor(name, area) {\n    this.name = name;\n    this.area = area;\n  }\n\n  static areEqual(shape1, shape2) {\n    return shape1.name === shape2.name \u0026\u0026 shape1.area === shape2.area;\n  }\n}\n\nconst s1 = new Shape(\"square\", 100);\nconst s2 = new Shape(\"square\", 100);\n\nconsole.log(Shape.areEqual(s1, s2)); // true\n```\n\n\u003e 🔒 You cannot call a static method from an instance:\n\n```\ns1.areEqual // ❌ Error\n```\n\n- Static methods are useful for utility/helper logic.\n\n### Access Modifiers in JS (Public, Protected, Private)\n\nJavaScript supports access control through naming conventions and private syntax.\n\n### 1️⃣ **Public Properties** (Default)\n\n```\nclass User {\n  constructor(name) {\n    this.name = name;\n    this.type = \"admin\";\n  }\n}\n\nconst user = new User(\"Ahad\");\nconsole.log(user.name);      // Ahad\nuser.type = \"normal\";        // Directly accessible\n```\n\n### 2️⃣ **Protected (Convention)** using `_underscore`\n\nJavaScript doesn't have real protected, but we use \\_ to indicate internal use.\n\n```\nclass User {\n  constructor(name) {\n    this.name = name;\n    this._type = \"admin\";\n  }\n\n  get type() {\n    return this._type;\n  }\n\n  set type(val) {\n    if (val === \"admin\" || val === \"normal\") {\n      this._type = val;\n    } else {\n      throw new Error(\"Only 'admin' or 'normal' allowed\");\n    }\n  }\n}\n\nconst user = new User(\"Ahad\");\nuser.type = \"normal\";         // ✅ setter used\nconsole.log(user.type);       // normal\n```\n\n### 3️⃣ **Private Properties** (Truly Private using #)\n\nIntroduced in ES2022+\n\n```js\nclass User {\n  #type = \"admin\";\n\n  constructor(name) {\n    this.name = name;\n  }\n\n  get type() {\n    return this.#type;\n  }\n\n  set type(val) {\n    if (val === \"admin\" || val === \"normal\") {\n      this.#type = val;\n    } else {\n      throw new Error(\"Only 'admin' or 'normal' allowed\");\n    }\n  }\n}\n\nconst user = new User(\"Ahad\");\nuser.type = \"normal\";\nconsole.log(user.type); // normal\n\n// ❌ Error: cannot access private field\n// console.log(user.#type);\n```\n\n- Use for true encapsulation and safety.\n\n### `instanceof`\n\nUsed to check inheritance relationships:\n\n```\nrect1 instanceof Rectangle // true\nrect1 instanceof Shape     // true\n\n```\n\n---\n\n## ❓ What is the Difference Constructor Function and Factory Function?\n\n| Feature        | Constructor Function        | Factory Function               |\n|----------------|-----------------------------|--------------------------------|\n| Syntax         | Uses `new` keyword          | Regular function               |\n| `this` usage   | Uses `this` internally      | Returns object directly        |\n| Reusability    | Supports prototypes         | Uses closures or literals      |\n\n```js\n// Constructor Function\nfunction Person(name) {\n  this.name = name;\n}\nlet p1 = new Person(\"Ahad\");\n\n// Factory Function\nfunction createPerson(name) {\n  return { name };\n}\nlet p2 = createPerson(\"Ahad\");\n```\n\n---\n\n## ❓ What is an Array in JavaScript?\n\nAn **array** in JavaScript is a special type of variable that can hold **multiple values** at once.\n\nArrays are used to store collections of data, such as:\n\n- A list of numbers\n- A list of strings\n- A mix of data types (number, string, object, boolean, etc.)\n\n- Zero-based indexing (starts from 0)\n- Dynamically sized\n- Can hold any type of data\n\n```js\nlet numbers = [1, 2, 3, 4, 5];\nconsole.log(numbers[0]); // Output: 1\n```\n\n```js\nlet mixedArray = [\n  42,\n  \"Ahad\",\n  true,\n  { role: \"dev\" },\n  function () {\n    return \"hello\";\n  },\n];\nconsole.log(mixedArray[3].role); // Output: \"dev\"\nconsole.log(mixedArray[4]()); // Output: \"hello\"\n```\n\n### Array Methods:\n\n| Method      | Description                          |\n| ----------- | ------------------------------------ |\n| `push()`    | Add element to end                   |\n| `pop()`     | Remove last element                  |\n| `shift()`   | Remove first element                 |\n| `unshift()` | Add element to start                 |\n| `map()`     | Transform items and return new array |\n| `filter()`  | Filter items based on condition      |\n| `forEach()` | Run a function for each item         |\n\n---\n\n## ❓ What is the Difference between `forEach()`, `map()`, `filter()`, `reduce()`, `find()`, `some()`, `every()` in JavaScript?\n\n### `forEach()`\n\n- Used to loop through an array and perform actions on each item.\n- **Does not return** a new array.\n\n```js\nconst numbers = [1, 2, 3, 4];\nnumbers.forEach((num) =\u003e {\n  console.log(num * 2); // Output: 2, 4, 6, 8\n});\n```\n\n### `map()`\n\n- Creates a **new array** by transforming each element.\n- Does **not modify** the original array.\n\n```js\nconst numbers = [1, 2, 3, 4];\nconst doubled = numbers.map((num) =\u003e num * 2);\n\nconsole.log(doubled); // [2, 4, 6, 8]\nconsole.log(numbers); // [1, 2, 3, 4]\n```\n\n### `filter()`\n\n- Returns a **new array** with elements that pass the provided test.\n\n```js\nconst numbers = [1, 2, 3, 4, 5, 6];\nconst even = numbers.filter((num) =\u003e num % 2 === 0);\n\nconsole.log(even); // [2, 4, 6]\n```\n\n### `reduce()`\n\n- Reduces an array to a **single value** using a function.\n- Useful for totals, sums, or constructing objects.\n\n```js\nconst numbers = [1, 2, 3, 4, 5];\nconst sum = numbers.reduce((acc, num) =\u003e acc + num, 0);\n\nconsole.log(sum); // 15\n```\n\n### `find()`\n\n- Returns the **first element** that matches the condition.\n- Returns `undefined` if not found.\n\n```js\nconst numbers = [1, 2, 3, 4, 5];\nconst found = numbers.find((num) =\u003e num \u003e 3);\n\nconsole.log(found); // 4\n```\n\n### `some()`\n\n- Checks if **at least one** element satisfies the condition.\n- Returns `true` or `false`.\n\n```js\nconst nums = [1, 2, 3, 4];\nconsole.log(nums.some((num) =\u003e num \u003e 2)); // true\n```\n\n### `every()`\n\n- Checks if **all** elements satisfy the condition.\n- Returns `true` or `false`.\n\n```js\nconst nums = [1, 2, 3, 4];\nconsole.log(nums.every((num) =\u003e num \u003e 0)); // true\n```\n\n### Array Methods \u0026 Behavior\n\n| Method      | Purpose                          | Returns New Array? | Modifies Original?   | Notes                      |\n| ----------- | -------------------------------- | ------------------ | -------------------- | -------------------------- |\n| `forEach()` | Loop \u0026 perform action            | ❌ No              | ✅ Yes (if modified) | No return                  |\n| `map()`     | Transform each element           | ✅ Yes             | ❌ No                | Shallow copy               |\n| `filter()`  | Filter elements                  | ✅ Yes             | ❌ No                | Shallow copy               |\n| `reduce()`  | Reduce array to a single value   | ❌ No              | ❌ No                | Accumulator-based          |\n| `find()`    | Find first match                 | ❌ No              | ❌ No                | Returns value or undefined |\n| `some()`    | At least one element passes test | ❌ No              | ❌ No                | Boolean                    |\n| `every()`   | All elements pass test           | ❌ No              | ❌ No                | Boolean                    |\n\n---\n\n## ❓ What is the Difference Between `slice()` and `splice()` in JavaScript?\n\n### ✂️ `slice()`\n\n- Extracts a **portion** of an array.\n- **Does not** modify the original array.\n- Returns a **new array**.\n\n```js\nlet numbers = [1, 2, 3, 4, 5];\nlet sliced = numbers.slice(1, 4);\n\nconsole.log(sliced); // [2, 3, 4]\nconsole.log(numbers); // [1, 2, 3, 4, 5]\n```\n\n### 🧨 `splice()`\n\n- Used to **add/remove** items from an array.\n- **Modifies** the original array.\n- Returns an array of **removed elements**.\n\n```js\nlet numbers = [1, 2, 3, 4, 5];\nlet removed = numbers.splice(1, 2); // start at index 1, remove 2 items\n\nconsole.log(removed); // [2, 3]\nconsole.log(numbers); // [1, 4, 5]\n```\n\n### `slice()` vs `splice()`\n\n| Method     | Returns New Array? | Modifies Original? | Use Case            |\n| ---------- | ------------------ | ------------------ | ------------------- |\n| `slice()`  | ✅ Yes             | ❌ No              | Extract portion     |\n| `splice()` | ✅ Yes (removed)   | ✅ Yes             | Add/remove elements |\n\n---\n\n## ❓ What is the Ternary Operator in JavaScript?\n\nThe **ternary operator** is a **shorthand version of the `if...else` statement** in JavaScript.\nIt allows you to write **conditional expressions** in a single line using three parts:\n\n```js\ncondition ? expression_if_true : expression_if_false;\n```\n\n```js\nlet marks = 18;\nlet result = marks \u003e= 40 ? \"Pass\" : \"Fail\";\n\nconsole.log(result); // Output: \"Fail\"\n```\n\n### Explanation:\n\n| Part          | Description                        |\n| ------------- | ---------------------------------- |\n| `marks \u003e= 40` | Condition to check                 |\n| `'Pass'`      | Executes if condition is **true**  |\n| `'Fail'`      | Executes if condition is **false** |\n\n### Why use the Ternary Operator?\n\n- Cleaner and more readable than `if...else` for short conditions.\n- Ideal for **inline decisions** like setting values or rendering content.\n\n```js\nlet age = 20;\nlet status = age \u003e= 18 ? \"Adult\" : \"Minor\";\nconsole.log(status); // \"Adult\"\n\nlet isLoggedIn = false;\nlet message = isLoggedIn ? \"Welcome back!\" : \"Please log in\";\nconsole.log(message); // \"Please log in\"\n```\n\n\u003e Use ternary operators for **simple conditions only**.\n\u003e\n\u003e For complex logic, stick with `if...else` blocks for better readability.\n\n---\n\n## ❓ What is the Difference between Rest and Spread Operator in JavaScript?\n\nBoth **Rest** and **Spread** operators use the same syntax `...` but serve **different purposes** depending on context.\n\n### Rest Operator (`...rest`)\n\n- **Collects multiple elements** into a single array or object.\n- Common in **function parameters** and **destructuring**.\n\n#### 1. Rest in Function Parameters\n\n```js\nfunction print(...rest) {\n  return rest;\n}\nconsole.log(print(1, 2, 3)); // [1, 2, 3]\n```\n\n- All arguments passed to `print` are **gathered into an array**.\n\n#### 2. Rest in Array Destructuring\n\n```js\nconst [...rest] = [1, 2, 3];\nconsole.log(rest); // [1, 2, 3]\n```\n\n- All elements collected into `rest`.\n\n#### 3. Rest for Calculations\n\n```js\nfunction sum(...args) {\n  return args.reduce((a, b) =\u003e a + b);\n}\nconsole.log(sum(1, 2, 3, 4)); // 10\n```\n\n### Spread Operator (`...spread`)\n\n- **Expands** arrays/objects into **individual elements**.\n- Used in **combining, copying, and passing elements**.\n\n#### 1. Spread to Combine Arrays\n\n```js\nconst arr = [1, 2, 3];\nconst newArr = [...arr, 4, 5];\nconsole.log(newArr); // [1, 2, 3, 4, 5]\n```\n\n#### 2. Spread to Merge Arrays\n\n```js\nconst arr1 = [1, 2, 3];\nconst arr2 = [4, 5, 6];\nconst combined = [...arr1, ...arr2];\nconsole.log(combined); // [1, 2, 3, 4, 5, 6]\n```\n\n#### 3. Spread to Copy Array\n\n```js\nconst original = [1, 2, 3];\nconst copy = [...original];\nconsole.log(copy); // [1, 2, 3]\n```\n\n### Destructuring in JavaScript\n\nDestructuring lets you **unpack values** from arrays or objects into **separate variables**.\n\n#### Destructuring Arrays\n\n```js\nconst arr = [1, 2, 3];\nconst [a, b, c] = arr;\n\nconsole.log(a); // 1\nconsole.log(b); // 2\nconsole.log(c); // 3\n```\n\n#### Array Destructuring with Rest\n\n```js\nconst [first, second, ...rest] = [1, 2, 3, 4, 5];\n\nconsole.log(first); // 1\nconsole.log(second); // 2\nconsole.log(rest); // [3, 4, 5]\n```\n\n#### Object Destructuring with Rest\n\n```js\nconst user = { name: \"Abdul Ahad\", age: 30, role: \"admin\" };\nconst { name, ...details } = user;\n\nconsole.log(name); // Abdul Ahad\nconsole.log(details); // { age: 30, role: 'admin' }\n```\n\n| Feature           | Rest Operator (`...rest`)           | Spread Operator (`...spread`)           |\n| ----------------- | ----------------------------------- | --------------------------------------- |\n| Purpose           | Gathers items into one array/object | Spreads elements into individual values |\n| Use Case          | Function params, destructuring      | Array copy, merge, pass as args         |\n| Syntax Position   | On the **receiving** side           | On the **sending** side                 |\n| Return Value      | Always returns array or object      | Expands into individual values          |\n| Changes Original? | ❌ No                               | ❌ No                                   |\n\n### Rest Example (Function Arguments)\n\n```js\nfunction sum(...numbers) {\n  return numbers.reduce((acc, curr) =\u003e acc + curr, 0);\n}\nconsole.log(sum(1, 2, 3, 4, 5)); // 15\n```\n\n### Spread Example (Merge Arrays)\n\n```js\nlet numbers = [1, 2, 3];\nlet newNumbers = [...numbers, 4, 5];\nconsole.log(newNumbers); // [1, 2, 3, 4, 5]\n```\n\n---\n\n## ❓ What are Different Data Types in JavaScript?\n\nJavaScript has two main categories of data types:\n\n### 1. Primitive Data Types\n\n- Stored **by value** (directly in the **stack**)\n- **Immutable** — cannot be changed once created\n- Simple \u0026 fast\n\n#### Types:\n\n| Type        | Example                |\n| ----------- | ---------------------- |\n| `Number`    | `let age = 25;`        |\n| `String`    | `let name = \"Ahad\";`   |\n| `Boolean`   | `let isOnline = true;` |\n| `Null`      | `let x = null;`        |\n| `Undefined` | `let y;`               |\n| `Symbol`    | `let id = Symbol();`   |\n| `BigInt`    | `let big = 123n;`      |\n\n\u003e ✅ **Primitive values are compared by their actual value.**\n\n### 2. Reference Data Types (Non-Primitives)\n\n- Stored **by reference** (in the **heap**)\n- **Mutable** — can be modified after creation\n- Can store **multiple values**\n\n#### Types:\n\n| Type                       | Example                             |\n| -------------------------- | ----------------------------------- |\n| `Object`                   | `let user = { name: \"Ahad\" };`      |\n| `Array`                    | `let nums = [1, 2, 3];`             |\n| `Function`                 | `function greet() { return \"Hi\"; }` |\n| `Date`, `Set`, `Map`, etc. | More complex structures             |\n\n\u003e ❗ When you copy reference types, you're copying the **reference**, not the actual value.\n\n| Feature    | Primitive           | Reference       |\n| ---------- | ------------------- | --------------- |\n| Stored in  | Stack               | Heap            |\n| Copy Type  | By Value            | By Reference    |\n| Mutability | Immutable           | Mutable         |\n| Comparison | Value-based (`===`) | Reference-based |\n\n```js\n// Primitive\nlet a = 5;\nlet b = a;\nb = 10;\nconsole.log(a); // 5 ✅ original unchanged\n\n// Reference\nlet obj1 = { name: \"Ahad\" };\nlet obj2 = obj1;\nobj2.name = \"Ali\";\nconsole.log(obj1.name); // \"Ali\" ❗ changed because it's the same reference\n```\n\n- Use **primitive types** for simple, fixed values.\n- Use **reference types** for collections, structured data, and behaviors.\n\n---\n\n## ❓ What is the Difference between `==` and `===`\n\nBoth `==` and `===` are used for **comparison**, but they behave differently.\n\n### `==` (Loose Equality)\n\n- Performs **type coercion**\n- Converts operands to the same type before comparing\n\n```js\n5 == \"5\"; // true\ntrue == 1; // true\nnull == undefined; // true\n```\n\n\u003e ⚠️ Can cause **unexpected results** due to automatic type conversion.\n\n### `===` (Strict Equality)\n\n- **No type coercion**\n- Compares both **value and type**\n\n```js\n5 === \"5\"; // false\ntrue === 1; // false\nnull === undefined; // false\n```\n\n\u003e More **predictable** and recommended in most cases.\n\n### Bonus: Operator Behavior Examples\n\n```js\nconsole.log(1 + 2 + 3); // 6\nconsole.log(\"1\" + \"2\" + \"3\"); // \"123\"\nconsole.log(1 + 2 + \"3\"); // \"33\"\nconsole.log(1 + \"2\" + \"2\"); // \"122\"\nconsole.log(1 + 2 + \"3\" + 4 + 5); // \"3345\"\n\nconsole.log(false - 1); // -1\nconsole.log(true + 1); // 2\n\nconsole.log([1] + \"abc\"); // \"1abc\"\nconsole.log(1 + \"2\" + +\"2\"); // \"122\"\nconsole.log(1 + +\"2\" + \"2\"); // \"32\"\nconsole.log(1 + -\"1\" + \"2\"); // \"02\"\nconsole.log(1 + \"1\" + -\"2\"); // \"11-2\"\n\nconsole.log(\"A\" - \"B\" + \"2\"); // \"NaN2\"\nconsole.log(\"A\" - \"B\" + 2); // NaN\n```\n\n---\n\n## ❓ What is Referential Equality?\n\nReferential equality checks if **two variables refer to the same object in memory**.\n\n- Primitives (`string`, `number`, `boolean`, etc.) are compared **by value**.\n- Objects (`{}`, `[]`, `function`) are compared **by reference**.\n\n```js\nlet a = { name: \"Ahad\" };\nlet b = a;\nconsole.log(a === b); // ✅ true (same reference)\n\nlet c = { name: \"Ahad\" };\nconsole.log(a === c); // ❌ false (different object, same content)\n```\n\n---\n\n## ❓ What is the Difference between `null` and `undefined`\n\nBoth `null` and `undefined` represent \"empty\" or \"missing\" values, but they are **not the same**.\n\n### `undefined`\n\n- A variable is **declared** but **not assigned** a value.\n- Automatically assigned by JavaScript if no value is set.\n\n```js\nlet a;\nconsole.log(a); // undefined\n```\n\n### `null`\n\n- Manually assigned to indicate \"no value\" or \"intentionally empty\".\n- Used when you want to clear a value on purpose.\n\n```js\nlet b = null;\nconsole.log(b); // null\n```\n\n### Comparison\n\n```js\nlet a;\nlet b = null;\n\nconsole.log(a === b); // false - different types\nconsole.log(a == b); // true  - loosely equal\n```\n\n- === compares both value and type\n- == performs type coercion, so null and undefined are treated as equal\n\n\u003e Use null when you want to intentionally reset a variable.\n\u003e Be cautious with == — it can produce unexpected results due to type coercion.\n\n---\n\n## ❓ What is NaN?\n\n**NaN** stands for **\"Not-a-Number\"**.\n\nIt is a special value in JavaScript used to represent **an invalid number** — the result of an operation that **fails to return a meaningful numeric value**.\n\n```javascript\nconsole.log(0 / 0); // NaN (undefined division)\nconsole.log(\"abc\" - 10); // NaN (invalid subtraction)\nconsole.log(Math.sqrt(-1)); // NaN (imaginary number)\nconsole.log(parseInt(\"xyz\")); // NaN\n```\n\n- `NaN` is a number type:\n\n```js\nconsole.log(typeof NaN); // Output: \"number\"\n```\n\n- It does not equal itself:\n\n```js\nconsole.log(NaN === NaN); // false\nconsole.log(Object.is(NaN, NaN)); // true (safe comparison)\n```\n\n- To check for `NaN`, use:\n\n```js\nconsole.log(Number.isNaN(NaN)); // true ✅\nconsole.log(Number.isNaN(\"hello\")); // false ✅\nconsole.log(isNaN(\"hello\")); // true ❌ (bad: coerces string to NaN first)\n```\n\n### Best Way to Check for NaN\n\n```js\nNumber.isNaN(value); // Strict and safe\n```\n\n```js\nconsole.log(Number.isNaN(\"abc\")); // false (it's a string, not NaN)\nconsole.log(Number.isNaN(NaN)); // true\n```\n\n### Real World Use Case\n\n```js\nfunction divide(a, b) {\n  if (b === 0) {\n    return NaN; // Division by zero\n  }\n  return a / b;\n}\n\nconsole.log(divide(10, 2)); // 5\nconsole.log(divide(10, 0)); // NaN\n```\n\n## ❓ What is Strict Mode in JavaScript?\n\n**Strict Mode** is a feature in JavaScript that helps you **write cleaner, more secure, and less error-prone code** by enabling **stricter parsing and error handling**.\n\nYou activate it by adding:\n\n```js\n\"use strict\";\n```\n\nIt can be applied:\n\n- At the top of a JS file\n- Inside a specific function block\n\n### Why Use Strict Mode?\n\nIt helps catch:\n\n- Silent errors\n- Accidental global variables\n- Invalid assignments\n- Deprecated or unsafe syntax\n\n\u003e Especially useful in large **codebases, teams**, or when using **classes/modules** (which are strict by default).\n\n### Enabling Strict Mode\n\n1. File-level\n\n```js\n\"use strict\";\nx = 10; // ❌ Error: x is not defined\n```\n\n2. Function-level\n\n```js\nfunction doSomething() {\n  \"use strict\";\n  y = 5; // ❌ Error: y is not defined\n}\n```\n\n\u003e 💡 Note: ES6 class syntax always runs in strict mode automatically.\n\n### Common Errors Caught by Strict Mode\n\n| 🔍 Mistake                                     | ❌ Without Strict  | ✅ With Strict  |\n| ---------------------------------------------- | ------------------ | --------------- |\n| Using undeclared variables                     | Allowed silently   | ❌ Throws error |\n| Assigning to read-only/global                  | No warning         | ❌ Throw","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahadalireach%2Fjavascript.interview.questions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahadalireach%2Fjavascript.interview.questions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahadalireach%2Fjavascript.interview.questions/lists"}