<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Saumya Agrawal]]></title><description><![CDATA[The blogs are my way to showcase my learnings ]]></description><link>https://blog.saumyagrawal.in</link><image><url>https://cdn.hashnode.com/uploads/logos/678b775e773554ab7117f20a/195f761d-2130-4997-9213-bc3efd66aa8c.png</url><title>Saumya Agrawal</title><link>https://blog.saumyagrawal.in</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Apr 2026 12:41:27 GMT</lastBuildDate><atom:link href="https://blog.saumyagrawal.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Error Handling]]></title><description><![CDATA[Every developer learns this eventually, usually at the worst possible time. You write something, it works on your machine, you ship it, and then a user does something you didn't predict, types letters]]></description><link>https://blog.saumyagrawal.in/error-handling</link><guid isPermaLink="true">https://blog.saumyagrawal.in/error-handling</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Thu, 26 Mar 2026 07:18:50 GMT</pubDate><content:encoded><![CDATA[<p>Every developer learns this eventually, usually at the worst possible time. You write something, it works on your machine, you ship it, and then a user does something you didn't predict, types letters into a number field, loses their internet connection mid-request, passes in an empty string where you expected an array. The code falls over.</p>
<p>The mistake isn't that the code broke. That's going to happen. The mistake is not planning for it. A user who hits an unhandled error sees nothing useful. You, the developer, also see nothing useful, no message, no context, no idea what went wrong. Compare that to code that catches the error, logs it properly, and shows the user something sensible. Same breakage, completely different experience for everyone involved.</p>
<p>Before getting into how to handle errors, it's worth knowing the types you'll actually run into. There are three that show up constantly.</p>
<p><strong>ReferenceError:</strong> You used a variable that doesn't exist. Usually a typo or a scoping problem.</p>
<p><strong>TypeError:</strong> You tried to call something that isn't a function, or access a property on <code>null</code> or <code>undefined</code>.</p>
<p><strong>SyntaxError:</strong> The code itself is malformed. A missing bracket, a bad JSON string. Usually caught before the script even runs.</p>
<p><strong>RangeError:</strong> A value is outside an acceptable range.</p>
<p><strong>NetworkError:</strong> Not a built-in JS type, but the most common runtime failure. The fetch failed. The API timed out. The user went offline.</p>
<h2><strong>Try and Catch</strong></h2>
<p>The fix for unhandled errors is a <code>try...catch</code> block. Put the code that might fail inside <code>try</code>. If it throws, JavaScript jumps straight to <code>catch</code> and hands you the error object. The rest of <code>try</code> doesn't run and nothing crashes.</p>
<pre><code class="language-javascript">try {
  // This will throw a ReferenceError
  const result = undeclaredVariable * 2;
  console.log(result); // never runs
} catch (err) {
  // err is the Error object JavaScript created
  console.log(err.name);    // "ReferenceError"
  console.log(err.message); // "undeclaredVariable is not defined"
}

// Code runs normally
console.log("we're still going");
</code></pre>
<p>The error object always has two properties you'll use: <code>name</code> tells you the type of error, and <code>message</code> tells you what went wrong. In modern environments there's also <code>stack</code>, which gives you the full call trace. That one is invaluable when you're debugging something three functions deep.</p>
<p>One thing that trips people up: <code>try...catch</code> only works on runtime errors. If your code has a syntax error, JavaScript never runs the block at all. And if you're working with async code, a plain <code>try...catch</code> won't catch promise rejections unless you're inside an <code>async</code> function. There's a separate section on that below.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b943c6cc-f0b9-4d8b-b84c-c9368d4c140e.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>The Finally Block</strong></h2>
<p>There's a third part to the pattern that a lot of people skip until they actually need it. <code>finally</code> runs no matter what. Whether the <code>try</code> succeeded, whether <code>catch</code> ran, whether someone threw again inside <code>catch</code>. It doesn't matter. <code>finally</code> runs.</p>
<p>The use case is cleanup. If you opened a database connection, you need to close it. If you set a loading spinner to visible, you need to hide it. These things should happen regardless of whether the operation worked. That's exactly what <code>finally</code> is for.</p>
<pre><code class="language-javascript">async function loadUserData(id) {
  showSpinner(); // loading starts

  try {
    const res  = await fetch(`/api/users/${id}`);
    const data = await res.json();
    renderProfile(data);
  } catch (err) {
    showErrorMessage("Couldn't load profile. Try again.");
    console.error(err);
  } finally {
    hideSpinner(); // always runs 
  }
}
</code></pre>
<p>Without <code>finally</code>, you'd have to call <code>hideSpinner()</code> in both the success path and the <code>catch</code> block. That's easy to forget, especially when the function grows. <code>finally</code> means you write that cleanup logic once and it always runs.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/8cc91f93-151f-41e0-a96a-2fecb4789658.png" alt="" style="display:block;margin:0 auto" />

<p>A good mental model: <code>try</code> is the attempt, <code>catch</code> is the fallback, <code>finally</code> is the cleanup.</p>
<h2><strong>Throwing Custom Errors</strong></h2>
<p>JavaScript lets you throw errors yourself with the <code>throw</code> keyword. You can technically throw anything, a string, a number, an object. In practice, always throw an <code>Error</code> object. That's because <code>Error</code> objects include a stack trace automatically, which is the thing you actually want when debugging.</p>
<pre><code class="language-javascript">function divide(a, b) {
  if (b === 0) {
    throw new Error("Division by zero is not allowed");
  }
  return a / b;
}

try {
  divide(10, 0);
} catch (err) {
  console.log(err.message); // "Division by zero is not allowed"
}
</code></pre>
<p>For bigger applications, you'll want to extend <code>Error</code> with custom classes. This way a <code>catch</code> block can check what kind of error it got and respond differently, show a 404 UI for not-found errors, show a login prompt for auth errors, and so on.</p>
<pre><code class="language-javascript">class NotFoundError extends Error { 
    constructor(resource) { 
        super(${resource} not found); 
        this.name = "NotFoundError"; 
        this.resource = resource; 
      } 
}
class AuthError extends Error { 
    constructor(msg) { 
        super(msg); 
        this.name = "AuthError";
    }
}
async function getPost(id) { 
    const res = await fetch(/api/posts/${id});

    if (res.status === 401) throw new AuthError("Session expired"); 
    if (res.status === 404) throw new NotFoundError("post");
    return res.json(); 
}

try { 
    await getPost(99); 
} catch (err) { 
    if (err instanceof AuthError) redirectToLogin(); 
    if (err instanceof NotFoundError) show404Page(); 
    else showGenericError(err.message); 
}
</code></pre>
<p>The <code>instanceof</code> check is what makes this pattern useful. One <code>catch</code> block, multiple kinds of failure, each handled differently. And if something unexpected comes through, the <code>else</code> branch catches it so nothing goes silently missing.</p>
<h2><strong>Why This Matters</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/2490cecc-5c50-4918-a358-916081994389.png" alt="" style="display:block;margin:0 auto" />

<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">MDN Web Docs : try...catch</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error">MDN Web Docs : Error object</a></p>
</li>
<li><p><a href="https://javascript.info/try-catch">javascript.info : Error handling, "try...catch"</a></p>
</li>
<li><p><a href="https://javascript.info/custom-errors">javascript.info : Custom errors, extending Error</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Callback Functions]]></title><description><![CDATA[Before callbacks make sense, one thing has to click: in JavaScript, a function is a value. Like a number. Like a string. You can store it in a variable, pass it to another function, even return it fro]]></description><link>https://blog.saumyagrawal.in/callback-functions</link><guid isPermaLink="true">https://blog.saumyagrawal.in/callback-functions</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:44:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a93e2680-813f-4ccc-bd11-412ac673164d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before callbacks make sense, one thing has to click: in JavaScript, a function is a value. Like a number. Like a string. You can store it in a variable, pass it to another function, even return it from one. Most people know this in theory and then forget it the moment they try to use it.</p>
<p>Here's what that looks like in practice:</p>
<pre><code class="language-javascript">// Storing a function in a variable 
const greet = function(name) {
  console.log("Hello, " + name);
};

// Passing that variable to another function
function run(fn) {
  fn("Aditya"); // calls whatever was passed in
}

run(greet); // prints: Hello, Aditya
</code></pre>
<p><code>greet</code> is just a value here. We handed it to <code>run</code>, and <code>run</code> called it. That's the whole mechanic. A callback is just a function passed to another function so that other function can call it later.</p>
<p>The word "callback" sounds formal, but the idea is simple: you're giving someone your phone number and saying "call me back when you're done." The function you pass is that phone number.</p>
<h2><strong>Passing Functions as Arguments</strong></h2>
<p>You've probably used callbacks already without noticing. <code>addEventListener</code>, <code>setTimeout</code>, <code>Array.forEach</code>, all of these take a function as an argument. That function is the callback.</p>
<pre><code class="language-javascript">// setTimeout takes a callback: runs it after 2 seconds
setTimeout(function() {
  console.log("Two seconds later");
}, 2000);

// forEach takes a callback: runs it once per item
["Manas", "Saumya", "Priya"].forEach(function(name) {
  console.log(name);
});

// addEventListener takes a callback: runs it on click
button.addEventListener("click", function() {
  console.log("Clicked");
});
</code></pre>
<p>Notice the pattern. You pass a function, something else holds onto it, and calls it at the right moment. You are not in charge of <em>when</em> it runs. That's kind of the point.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/e97ae593-2727-449f-bf5e-1433d09e12ca.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Why Async Even Needs Callbacks</strong></h2>
<p>JavaScript runs one thing at a time. There is no threading, no parallel execution of your code. One call stack, one line at a time. So when you need to wait for something, a network request, a file read, a timer, you have a problem: if you wait, everything else stops.</p>
<p>Think about a restaurant. The chef doesn't stand at the kitchen pass staring at your food until you come collect it. They put it on the counter, ring a bell, and move on to the next order. You come when you're ready. The kitchen keeps running.</p>
<p>Callbacks are that bell. You hand the runtime a function and say: when the thing is done, run this. Meanwhile, the rest of your code keeps going.</p>
<pre><code class="language-javascript">// SYNCHRONOUS: second log waits for the whole loop
console.log("start");
for (let i = 0; i &lt; 1000000000; i++) {} // browser hangs here
console.log("end");

// ASYNC WITH CALLBACK: second log runs immediately
console.log("start");
setTimeout(function() {
  console.log("I ran later"); // runs after 2s, non-blocking
}, 2000);
console.log("end"); // this prints before the callback
</code></pre>
<p>Running that second block, you'll see "start", then "end", then two seconds later "I ran later". The callback didn't block anything.</p>
<h2><strong>Common Places Callbacks Show Up</strong></h2>
<p>Callbacks are everywhere. Once you start seeing the pattern, you can't unsee it. Here are the places you'll hit them most as a beginner.</p>
<pre><code class="language-javascript">// array methods: forEach, filter, map
const scores = [42, 88, 61, 95, 37];

// forEach: run callback for each item
scores.forEach(function(score) {
  console.log(score);
});

// filter: keep items where callback returns true
const passing = scores.filter(function(score) {
  return score &gt;= 60;
}); // [88, 61, 95]

// map: transform each item, return new array
const grades = scores.map(function(score) {
  return score &gt;= 60 ? "Pass" : "Fail";
}); // ["Fail", "Pass", "Pass", "Pass", "Fail"]
</code></pre>
<pre><code class="language-javascript">// Event Listeners
const btn = document.getElementById("submit");

// callback runs every time the button is clicked
btn.addEventListener("click", function(event) {
  event.preventDefault();
  console.log("Form submitted");
});
</code></pre>
<pre><code class="language-javascript">// fetch API
// fetch uses .then()  which takes a callback
fetch("/api/users/1")
  .then(function(response) {
    return response.json(); // callback 1: parse response
  })
  .then(function(data) {
    console.log(data.name); // callback 2: use the data
  });
</code></pre>
<p>Arrow functions are common shorthand for callbacks: <code>scores.filter(s =&gt; s &gt;= 60)</code> does the same thing as the <code>function</code> version above. Same idea, fewer keystrokes.</p>
<h2><strong>Writing Your Own Function That Takes a Callback</strong></h2>
<p>It helps to write one yourself, even if it's small. Once you've built a function that accepts and calls a callback, the whole model locks in.</p>
<pre><code class="language-javascript">// greetUser takes a name and a callback
function greetUser(name, callback) {
  console.log("Fetching user data...");
  callback(name); // call whatever was passed in
}

// Two different behaviours, same greetUser function
greetUser("Saumya", function(name) {
  console.log("Hello, " + name + "!"); // "Hello, Saumya!"
});

greetUser("Manas", function(name) {
  console.log("Welcome back, " + name); // "Welcome back, Manas"
});
</code></pre>
<p><code>greetUser</code> doesn't care what the callback does. It just calls it with the name. The caller decides the behaviour. That flexibility is exactly why callbacks are so useful — you write the structure once, plug in different logic as needed.</p>
<p>A real-world version of this is <code>Array.sort</code>. The sort algorithm is built into JavaScript, but you pass a callback that defines how to compare two items. You bring the comparison logic; sort brings the algorithm.</p>
<pre><code class="language-javascript">// sort with custom comparator callback
const users = [
  { name: "Manas",  age: 28 },
  { name: "Saumya", age: 24 },
  { name: "Priya",  age: 31 },
];

// sort needs to know HOW to compare — you provide that
users.sort(function(a, b) {
  return a.age - b.age; // youngest first
});
</code></pre>
<h2><strong>The Nesting Problem</strong></h2>
<p>Here's where callbacks get genuinely painful. Suppose you need to do three async things in sequence: fetch a user, then fetch their orders, then fetch the details of the first order. Each step depends on the previous one. With callbacks, you end up putting them inside each other.</p>
<pre><code class="language-javascript">getUser(1, function(user) {

  getOrders(user.id, function(orders) {

    getOrderDetails(orders[0].id, function(details) {

      console.log(details); // finally, the thing we wanted

    });
  });
});
</code></pre>
<p>Three levels. Now add error handling at each step. Add a fourth request. The indentation becomes a visual pyramid, and the logic is buried inside it. This has a name: callback hell.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/61b2e9ce-8cc0-44d1-8ccb-c43a42177a18.png" alt="" style="display:block;margin:0 auto" />

<p>The nesting itself is not wrong, it works. The problem is readability. Errors are hard to catch at the right level. Adding a step means nesting deeper. Debugging means tracing through a maze of closing braces. It gets old fast.</p>
<p>Callback hell is why Promises and async/await exist. They solve the same coordination problem with much flatter code. That's the next part of this series.</p>
<h2><strong>What Callbacks Actually Give You</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b5139a60-6750-4aee-ac1a-4a36a6ad6141.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Glossary/Callback_function">MDN Web Docs : Callback function</a></p>
</li>
<li><p>JavaScript.info : Introduction: callb<a href="https://javascript.info/callbacks">JavaScript.info : Introduction: callbacks</a></p>
</li>
<li><p><a href="https://nodejs.org/en/learn/asynchronous-work/javascript-asynchronous-programming-and-callbacks">JavaScript Asynchronous Programming and Callbacks</a></p>
</li>
<li><p><a href="http://callbackhell.com/">Callback Hell</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The New Keyword]]></title><description><![CDATA[You see new everywhere. new Date(). new Map(). new Promise(). You write it, it works, and you move on. But at some point you start wondering what it actually does. Calling a function with new in front]]></description><link>https://blog.saumyagrawal.in/the-new-keyword</link><guid isPermaLink="true">https://blog.saumyagrawal.in/the-new-keyword</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:11:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/af14c2f5-4379-4863-870f-d688a7b1a541.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You see <code>new</code> everywhere. <code>new Date()</code>. <code>new Map()</code>. <code>new Promise()</code>. You write it, it works, and you move on. But at some point you start wondering what it actually does. Calling a function with <code>new</code> in front behaves nothing like calling a function without it, and that gap is worth understanding.</p>
<p>Here is the short version: <code>new</code> runs a function in a special mode where that function builds and returns an object. The function is called a constructor. The object it builds is called an instance. That is the whole idea. The rest is just details about how it works.</p>
<p>A constructor is not a special kind of function. It is a regular function that you call with <code>new</code>. The convention is to capitalize the first letter so people know it is meant to be called that way, but JavaScript does not enforce this.</p>
<h2><strong>A Constructor Function</strong></h2>
<p>Before classes came along in ES6, this is how you made objects that shared a structure. You wrote a plain function, used <code>this</code> inside it, and called it with <code>new</code>. It still works exactly the same way today.</p>
<pre><code class="language-javascript">// Capital P signals: call this with new
function Person(name, age) {
  this.name = name;
  this.age  = age;
}

const priya = new Person("Priya", 28);
const rohan = new Person("Rohan", 34);

console.log(priya.name); // "Priya"
console.log(rohan.age);  // 34
</code></pre>
<p>Each call to <code>new Person()</code> produces a separate object. Priya's <code>name</code> and Rohan's <code>name</code> live on different objects. Changing one does not touch the other. That sounds obvious, but it is worth saying because it is the point.</p>
<h2><strong>What new Does</strong></h2>
<p>When JavaScript sees <code>new Person("Priya", 28)</code>, it does four things in order. You never see any of this happen, but it all runs before your function body even starts.</p>
<h4><strong>A blank object is created</strong></h4>
<p>JavaScript makes a fresh, empty object. Nothing in it yet. This is what will eventually come back from the call.</p>
<p>**<br />The prototype is linked**<br />That blank object gets its internal <code>[[Prototype]]</code> set to <code>Person.prototype</code>. This is how instances share methods without each one getting its own copy. More on this in a moment.</p>
<h4><strong>The function runs with this = that object</strong></h4>
<p>The constructor body runs, and every time you write <code>this.something</code>, you are writing onto that blank object from step 1.</p>
<h4><strong>The object is returned</strong></h4>
<p>Unless your constructor explicitly returns a different object, JavaScript returns the one it built in step 1. This is automatic. You do not write <code>return this</code>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/c43f77b4-37a0-4eb6-90c2-a2eeee6d3da2.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Where Methods Go: The Prototype</strong></h2>
<p>Here is something that trips people up early on. If you put a method inside the constructor body using <code>this.greet = function() {...}</code>, every single instance gets its own copy of that function. One hundred <code>Person</code> objects means one hundred separate <code>greet</code> functions sitting in memory, all doing the same thing.</p>
<p>The fix is to put shared methods on <code>Person.prototype</code> instead. Every instance automatically has access to it through the prototype chain, but only one copy exists.</p>
<pre><code class="language-javascript">// method in wrong places
function Person(name) {
  this.name = name;

  // Bad: every new Person() gets its own copy of this function
  this.greet = function() {
    console.log("Hi, I'm " + this.name);
  };
}
</code></pre>
<pre><code class="language-javascript">// method on the prototype
function Person(name) {
  this.name = name; // own property — each instance needs its own
}

// Defined once, shared by every Person instance
Person.prototype.greet = function() {
  console.log("Hi, I'm " + this.name);
};

const priya = new Person("Priya");
const rohan = new Person("Rohan");

priya.greet(); // "Hi, I'm Priya"
rohan.greet(); // "Hi, I'm Rohan"

// Same function object, just this changes per call
console.log(priya.greet === rohan.greet); // true
</code></pre>
<p>Own properties live on the instance. Methods that do not need unique per-instance data belong on the prototype. That line is where most of the judgment calls happen.</p>
<h2><strong>How Prototype Lookup Works</strong></h2>
<p>When you write <code>priya.greet()</code>, JavaScript looks for <code>greet</code> on <code>priya</code> itself first. It is not there. So it follows the internal <code>[[Prototype]]</code> link up to <code>Person.prototype</code> and looks there. It finds it. Done.</p>
<p>If it were not there either, it would keep climbing: <code>Object.prototype</code> is next. If it is not there, you get <code>undefined</code>. This chain of lookups is called the prototype chain, and it is the mechanism behind every method you call on any object in JavaScript.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/381abb3c-e56d-47a7-9c7e-92940056c156.png" alt="" style="display:block;margin:0 auto" />

<p>The practical upshot: methods on the prototype behave exactly like methods on the instance from the caller's perspective. You write <code>priya.greet()</code> either way. The lookup is invisible. You only notice it when you start asking questions like "where does <code>.toString()</code> come from on every object ever."</p>
<h2><strong>Forgetting new: What Goes Wrong</strong></h2>
<p>Call a constructor without <code>new</code> and JavaScript just runs it as a regular function. No blank object gets created. <code>this</code> inside it is not a fresh instance, it is either the global object (in non-strict mode) or <code>undefined</code> (in strict mode). In non-strict mode you get no error. You just silently write properties onto <code>window</code> and wonder why nothing is working.</p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

const oops = Person("Priya"); // no new

console.log(oops);        // undefined: function returned nothing
console.log(window.name);  // "Priya": oops, now it's global
</code></pre>
<p>In strict mode this at least throws a <code>TypeError</code> immediately, which is easier to catch. If you are writing constructor functions today, putting <code>"use strict"</code> at the top of your file is a reasonable safety net.</p>
<p>ES6 classes solve this permanently. A class constructor throws a <code>TypeError</code> if you call it without <code>new</code>, no matter what. That is one of the reasons classes exist.</p>
<h2><strong>Classes Do The Same Thing, With Better Guardrails</strong></h2>
<p>ES6 classes are not a different object model. They are a cleaner syntax over the same constructor function and prototype setup. If you understand constructors and prototypes, you already understand what classes compile down to.</p>
<pre><code class="language-javascript">//  constructor function
function Person(name, age) {
  this.name = name;
  this.age  = age;
}
Person.prototype.greet = function() {
  console.log("Hi, I'm " + this.name);
};

// class 
class Person {
  constructor(name, age) {
    this.name = name;
    this.age  = age;
  }
  greet() {
    console.log("Hi, I'm " + this.name);
  }
}

// Both produce instances with the same shape
const p = new Person("Priya", 28);
p.greet(); // "Hi, I'm Priya"
</code></pre>
<p>With the class syntax, <code>greet</code> is automatically placed on <code>Person.prototype</code>. You do not write that out manually. The engine handles it. The result is identical to the constructor function version, but there is less surface area for mistakes.</p>
<h2><strong>Constructor vs Instance</strong></h2>
<p>Properties and methods can live in three places: on the instance, on the prototype, or on the constructor function itself. Each one is used differently.</p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name; // instance property: unique per object
}

Person.prototype.greet = function() { // prototype method: shared
  console.log(this.name);
};

Person.count = 0; // static: lives on the constructor, not instances

const p = new Person("Priya");
p.greet();               // works. found on prototype
console.log(p.count);    // undefined. instances don't see static props
console.log(Person.count); // 0. access it through the constructor
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/cc615115-2c4a-4c1d-a9c9-4af95d13d38e.png" alt="" style="display:block;margin:0 auto" />

<p>If you want to test what you just read, try this: write a <code>Counter</code> constructor that stores a <code>count</code> on <code>this</code>, then add <code>increment</code> and <code>reset</code> methods on the prototype. Make two counters and verify they count independently. Then check that both counters share the same <code>increment</code> function reference.</p>
<p>That small exercise covers everything in this post. Own properties, shared methods, separate instances. Once that clicks, classes will feel like a notation change rather than a concept change, because you will already know what the class body is doing behind the scenes.</p>
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new">MDN Web Docs : new operator</a></p>
</li>
<li><p><a href="http://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">MDN Web Docs : Object prototypes</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Destructuring in JS]]></title><description><![CDATA[You have an object. It has properties. You want those properties as standalone variables. Before destructuring, you wrote one line per property. With destructuring, you write one line total.
That's th]]></description><link>https://blog.saumyagrawal.in/destructuring-in-js</link><guid isPermaLink="true">https://blog.saumyagrawal.in/destructuring-in-js</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Wed, 25 Mar 2026 06:36:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/5cb09309-b3ec-4f64-b6e8-01b4e189fc8c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You have an object. It has properties. You want those properties as standalone variables. Before destructuring, you wrote one line per property. With destructuring, you write one line total.</p>
<p>That's the whole thing. It's not a new data structure. It's not magic. It's a shorter way to pull values out of objects and arrays and assign them to variables in one shot.</p>
<p>It showed up in ES6 (2015) and now it's everywhere. You'll see it in React, Node, API responses, config files. Once you understand it, you'll spot it in every codebase you read.</p>
<p>Destructuring doesn't change the original object or array. It just copies values out into new variables. The source stays exactly as it was.</p>
<h2><strong>Objects First</strong></h2>
<p>Say you have a user object. The old way was to read each property individually. Three properties meant three lines. Twenty properties meant twenty lines, all with <code>user.</code> repeated like a broken record</p>
<pre><code class="language-javascript">// accessing objects
const user = {
  name: "User1",
  age: 28,
  city: "Delhi"
};

const name = user.name;
const age  = user.age;
const city = user.city;

// destructuring
const user = {
  name: "User1",
  age: 28,
  city: "Delhi"
};

const { name, age, city } = user;
// same result, one line
</code></pre>
<p>The curly braces on the left tell JavaScript: look inside <code>user</code> and find properties with these names. Create variables with those names. Done. The variable names match the property names exactly, so nothing is ambiguous.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/eeacad26-7aa7-4626-bbe9-121802c3075e.png" alt="" style="display:block;margin:0 auto" />

<p>You can pull out as many or as few properties as you need. You don't have to grab all of them. If <code>user</code> has ten properties and you only need <code>name</code> and <code>email</code>, just write those two.</p>
<pre><code class="language-javascript">// partial destructuring
const user = {
  name: "User1",
  age: 28,
  city: "Delhi",
  email: "user1@example.com",
  role: "admin"
};

// Only pull what you need, everything else stays in user
const { name, email } = user;
console.log(name);   // "User1"
console.log(email);  // "user1@example.com"
</code></pre>
<h2><strong>Destructuring Arrays</strong></h2>
<p>Arrays work the same way. Instead of curly braces you use square brackets, and instead of matching by name you match by position. First variable gets index 0, second gets index 1, and so on.</p>
<pre><code class="language-javascript">// before
const colors = ["red", "green", "blue"];

const first  = colors[0];
const second = colors[1];
const third  = colors[2];

// after
const colors = ["red", "green", "blue"];

const [first, second, third] = colors;

// first = "red", second = "green"
</code></pre>
<p>You name the variables yourself here, since arrays have no property names. Whatever you write inside the brackets becomes the variable name for that slot.</p>
<p>You can skip positions too. Leave a blank comma where you want to skip an index.</p>
<pre><code class="language-javascript">// skip positions
const scores = [88, 72, 95, 60];

// only grab first and third
const [first, , third] = scores;

console.log(first);  // 88
console.log(third);  // 95
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b6730c6d-d094-4853-bd6f-1e2e19339fd7.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Default Values</strong></h2>
<p>Sometimes a property doesn't exist in the object, or an array slot is empty. Without a default value, you get <code>undefined</code>. With one, you get a sensible fallback.</p>
<pre><code class="language-javascript">// default values in object destructuring
const settings = {
  theme: "dark"
  // no `fontSize` key in this object
};

const { theme, fontSize = 16 } = settings;

console.log(theme);     // "dark"   = came from the object
console.log(fontSize);  // 16      = used the default, key was missing
</code></pre>
<p>The default only kicks in when the value is <code>undefined</code>. If the object has the key and it's set to <code>null</code> or <code>0</code> or even an empty string, the default is ignored and you get whatever's actually there.</p>
<pre><code class="language-javascript">// defaults in array destructuring
const rgb = [255, 128];  // only two values, third is missing

const [r, g, b = 0] = rgb;

console.log(r);  // 255
console.log(g);  // 128
console.log(b);  // 0  = default used since index 2 didn't exist
</code></pre>
<p>Defaults make your code defensive without adding <code>if</code> statements. If an API sometimes returns an object without certain fields, destructuring with defaults handles the missing data in one line instead of three.</p>
<h2><strong>Renaming While Destructuring</strong></h2>
<p>Sometimes the property name in the object clashes with a variable you already have, or it's just not a clear name for what you're doing. You can rename it right in the destructure using a colon.</p>
<pre><code class="language-javascript">const response = {
  n: "User1",   // short API field name, not readable
  a: 28
};

// n becomes name, a becomes age 
const { n: name, a: age } = response;

console.log(name);  // "User1"
console.log(age);   // 28
// `n` and `a` no longer exist as variables, they became `name` and `age` 
</code></pre>
<p>You can also combine renaming with defaults in one go.</p>
<pre><code class="language-javascript">const config = { w: 800 };

const { w: width = 1024, h: height = 768 } = config;

console.log(width); // 800 = came from w 
console.log(height); // 768 = h missing, used default
</code></pre>
<h2><strong>Where You'll Actually Use This</strong></h2>
<p>The places destructuring shows up the most aren't random assignments, they're function parameters and API responses. These are worth seeing on their own.</p>
<p><strong>Function parameters.</strong> You can destructure right in the parameter list. The function still receives one object, but you name the fields you care about up front. The function body never repeats the parameter name.</p>
<pre><code class="language-javascript">// Without parameter destructuring
function greet(user) {
  return `Hi ${user.name},
you're ${user.age}.`;
}

// With parameter destructuring
function greet({ name, age }) {
  return `Hi ${name},
you're ${age}.`;
}
// greet({ name: "User1", age: 28 }) = "Hi User1, you're 28."
</code></pre>
<p><strong>API responses.</strong> You fetch data from a server. The response has a <code>data</code> field with a <code>user</code> inside. You need <code>name</code> and <code>email</code>. You can reach all the way in with one line.</p>
<pre><code class="language-javascript">// nested destructuring
const apiResponse = {
  status: 200,
  data: {
    user: {
      name: "User2",
      email: "user2@example.com"
    }
  }
};

// Reach three levels deep in one assignment
const { data: { user: { name, email } } } = apiResponse;

console.log(name);   // "User2"
console.log(email);  // "user2@example.com"
</code></pre>
<p>Deep nesting like this is fine when you know the structure. If any level might be missing (like <code>data</code> being <code>null</code>), combine it with optional chaining or check before destructuring. Nested destructuring on <code>undefined</code> throws an error.</p>
<h2><strong>What You Actually Get Out Of This</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/06956bde-9863-4d32-8128-d8f5c9648738.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">MDN Web Docs : Destructuring assignment</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Map & Set]]></title><description><![CDATA[Two situations come up all the time in JavaScript. You need to store key-value pairs where the keys are not strings. Or you need a list where every item appears exactly once. Both times, most people r]]></description><link>https://blog.saumyagrawal.in/map-set</link><guid isPermaLink="true">https://blog.saumyagrawal.in/map-set</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Tue, 24 Mar 2026 20:32:00 GMT</pubDate><content:encoded><![CDATA[<p>Two situations come up all the time in JavaScript. You need to store key-value pairs where the keys are not strings. Or you need a list where every item appears exactly once. Both times, most people reach for a plain object or an array. Both times, the tool kind of works but keeps surprising you in annoying ways.</p>
<p>User1 is building a permission system. They use a plain object to map user IDs to roles. Then they discover that <code>obj.toString</code> already exists as a key, so their code silently returns a built-in function instead of <code>undefined</code>. User2 is tracking which pages a visitor has seen. They push into an array and later realize the same URL got added three times. Both of them needed a different tool.</p>
<p>Objects and arrays are not wrong. They're just not built for these jobs. <code>Map</code> and <code>Set</code> are.</p>
<h2><strong>What Map is</strong></h2>
<p>A <code>Map</code> stores key-value pairs, exactly like an object. The difference is what it allows as keys. Objects only accept strings and symbols. A Map accepts anything: strings, numbers, booleans, other objects, DOM nodes, even functions.</p>
<p>It also keeps insertion order. You iterate a Map and the entries come back in the order you put them in. Objects are not guaranteed to do that, especially when the keys are numeric-looking strings.</p>
<pre><code class="language-javascript">const scores = new Map();

// String key 
scores.set("User1", 42);

// Number key- objects would convert this to a string, Map won't
scores.set(1001, 88);

// Object as key 
const userObj = { id: 7 };
scores.set(userObj, 95);

console.log(scores.get("User1"));   // 42
console.log(scores.get(1001));     // 88
console.log(scores.get(userObj));  // 95
console.log(scores.size);          // 3
</code></pre>
<p>Reading a key that doesn't exist returns <code>undefined</code>. Not a built-in function from the prototype chain. Not an inherited property. Just <code>undefined</code>. That alone removes a whole class of subtle bugs that plain objects invite.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/16e7c47a-78ce-4c86-adfb-119504e538d1.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>What Set is</strong></h2>
<p>A <code>Set</code> is a list where every value is unique. You add things to it and it keeps track of what it has already seen. Try adding the same value twice and the second one just gets ignored, no error, no duplicate.</p>
<p>That's it. The whole point is uniqueness. If you need a collection where order matters and duplicates are fine, use an array. If you need to track whether something exists and make sure there is only one of each, use a Set.</p>
<pre><code class="language-javascript">const visited = new Set();

visited.add("/home");
visited.add("/about");
visited.add("/home");  // duplicate gets silently ignored
visited.add("/contact");

console.log(visited.size);              // 3, not 4
console.log(visited.has("/about"));    // true
console.log(visited.has("/cart"));     // false

// Works for primitives and objects both
const ids = new Set([1, 2, 3, 2, 1]);
console.log([...ids]);  // [1, 2, 3]
</code></pre>
<p>One of the most common uses for Set is deduplication. Spread an array into a Set, then spread it back. Two characters of code, duplicates gone. No sorting, no <code>filter</code> with <code>indexOf</code>, no extra library.</p>
<pre><code class="language-javascript">// deduplicate an array
const tags = ["js", "css", "js", "html", "css"];
const unique = [...new Set(tags)];
console.log(unique); // ["js", "css", "html"]
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/97da042e-a5bc-4404-99fe-22624da28266.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Map vs Object</strong></h2>
<p>The instinct to reach for a plain object is strong. Objects are older, they're everywhere, and they look simpler. But they come with a few gotchas that Map avoids by design.</p>
<p>The biggest one is the prototype. Every plain object inherits properties from <code>Object.prototype</code>. That means keys like <code>"constructor"</code>, <code>"toString"</code>, or <code>"hasOwnProperty"</code> already exist on your object before you add anything. A Map starts completely empty.</p>
<pre><code class="language-javascript">// Plain object. prototype keys already exist
const obj = {};
console.log(obj.toString); // [Function: toString] = not undefined!

// Map, empty
const map = new Map();
console.log(map.get("toString")); // undefined = clean
</code></pre>
<pre><code class="language-javascript">// non-string keys
// Object silently converts numeric keys to strings
const obj = {};
obj[1]   = "one";
obj["1"] = "overwritten"; // same key = both point to "overwritten"

// Map keeps types intact
const map = new Map();
map.set(1,   "one");
map.set("1", "string one"); // different keys, both live
console.log(map.size); // 2
</code></pre>
<table>
<thead>
<tr>
<th>Map</th>
<th>Object</th>
</tr>
</thead>
<tbody><tr>
<td>Any key type (string, number, object, function)</td>
<td>String and Symbol keys only</td>
</tr>
<tr>
<td>No inherited prototype keys</td>
<td>Inherits from Object.prototype</td>
</tr>
<tr>
<td><code>.size</code> is a direct property</td>
<td>Size needs <code>Object.keys(obj).length</code></td>
</tr>
<tr>
<td>Insertion order is preserved</td>
<td>Numeric key order is implementation-defined</td>
</tr>
<tr>
<td>Built-in iteration with <code>for...of</code></td>
<td>JSON serialization works natively</td>
</tr>
<tr>
<td>Better performance for frequent add/delete</td>
<td>Better for static configs and known shapes</td>
</tr>
</tbody></table>
<h2><strong>Set vs Array</strong></h2>
<p>Arrays are ordered lists that allow duplicates and give you a ton of methods: <code>map</code>, <code>filter</code>, <code>reduce</code>, index access. Set is a membership structure. It tells you whether something is in the collection, quickly, and it enforces uniqueness automatically.</p>
<p>The tradeoff is simple. You cannot access a Set element by index. There is no <code>set[0]</code>. If you need that, use an array. But if you are asking "does this thing exist?" many times, Set is faster. Arrays run through every element with <code>includes()</code>. Set uses a hash lookup and answers in constant time.</p>
<pre><code class="language-javascript">const arr = ["User1", "User2", "User3"]; // could be thousands
const set = new Set(["User1", "User2", "User3"]);

// Array: scans from start, O(n)
arr.includes("User3"); // walks the whole list to be sure

// Set: hash lookup, O(1)
set.has("User3"); // answers immediately regardless of size
</code></pre>
<table>
<thead>
<tr>
<th>Set</th>
<th>Array</th>
</tr>
</thead>
<tbody><tr>
<td>Unique values, no duplicates possible</td>
<td>Allows duplicates</td>
</tr>
<tr>
<td><code>.has()</code> is fast regardless of size</td>
<td><code>.includes()</code> is O(n)</td>
</tr>
<tr>
<td>No index access</td>
<td>Index access with <code>arr[i]</code></td>
</tr>
<tr>
<td>No <code>map</code> or <code>filter</code> built in</td>
<td>Method map, filter, reduce, sort available</td>
</tr>
</tbody></table>
<h2><strong>When to Use Each One</strong></h2>
<p>Most of the confusion around Map and Set comes from not having a clear rule for when to switch. Here is a fairly clean one: if the answer to your problem involves the word "unique" or "exists", reach for Set. If it involves "look up by key" and the key is not a string, or you need guaranteed ordering, reach for Map.</p>
<pre><code class="language-javascript">// map
const user1 = { name: "User1", id: 1 };
const user2 = { name: "User2", id: 2 };

const scores = new Map();
scores.set(user1, 980);
scores.set(user2, 740);

// Iterate in insertion order
for (const [user, score] of scores) {
  console.log(`\({user.name}: \){score}`);
}
// User1: 980
// User2: 740
</code></pre>
<pre><code class="language-javascript">// set
// Track which users completed onboarding (no duplicates)
const completed = new Set();
completed.add("User1");
completed.add("User2");
completed.add("User1"); // ignored

function canProceed(userId) {
  return completed.has(userId);
}
console.log(canProceed("User1")); // true
console.log(canProceed("User3")); // false

// Remove an entry
completed.delete("User2");
console.log(completed.size); // 1
</code></pre>
<p>A useful mental shortcut: if you are storing a pair of things together, Map. If you are storing a single thing and just need to know it's there, Set.</p>
<h2><strong>What You Actually Get Out of This</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/771cb754-2970-4c10-98f7-cd4d8678b711.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENNCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map : MDN</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">Set : MDN</a></p>
</li>
<li><p><a href="https://javascript.info/map-set">Map and Set :</a> <a href="http://javascript.info">javascript.info</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Async JavaScript]]></title><description><![CDATA[JavaScript reads your code the same way you read a book: line one, line two, line three, in order. When it hits line five, lines one through four are already done. This is called synchronous execution]]></description><link>https://blog.saumyagrawal.in/async-javascript</link><guid isPermaLink="true">https://blog.saumyagrawal.in/async-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Mon, 23 Mar 2026 19:52:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b012da95-d266-4b3a-a855-9330af4fa13c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript reads your code the same way you read a book: line one, line two, line three, in order. When it hits line five, lines one through four are already done. This is called <strong>synchronous execution</strong>. Each task finishes before the next one starts.</p>
<p>Most of the time, that's fine. Adding numbers, updating a variable, looping through a list: these things happen in microseconds. Nothing needs to wait for anything.</p>
<pre><code class="language-javascript">// Each line runs and finishes before the next one starts
console.log("Step 1: make tea");
console.log("Step 2: add milk");
console.log("Step 3: drink it");

// Output, every time, in this exact order:
// Step 1: make tea
// Step 2: add milk
// Step 3: drink it
</code></pre>
<p>The problem shows up when one of those steps takes time. Fetching data from a server. Reading a file. Waiting on a timer. Suddenly "finish before moving on" becomes a real problem.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/f5be1f55-e899-4c85-bf84-6e1aba90ebb2.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>What Blocking Feels Like</strong></h2>
<p>JavaScript runs in one thread, like One lane on the highway. When something stops in that lane, everything behind it stops too. There's no overtaking.</p>
<p>Here's a fake slow operation that shows the problem clearly. The <code>slowTask()</code> function below ties up JavaScript for three full seconds. Nothing else happens during that time, no button clicks, no animations, no anything.</p>
<pre><code class="language-javascript">// blocking code 
function slowTask() {
  // Spin the CPU for 3 seconds. Nothing else runs during this.
  const end = Date.now() + 3000;
  while (Date.now() &lt; end) {}
}

console.log("Starting...");
slowTask();                   // browser freezes for 3 seconds
console.log("Done.");         // only prints after the freeze
</code></pre>
<p>A real network request works the same way if you wait synchronously. The difference is a spin loop wastes CPU. A network call mostly just sits there doing nothing while your app freezes. Either way, your user is staring at a dead screen.</p>
<p>This is why browsers started giving JavaScript a way to say "go do this, and tell me when it's done, but don't stop everything while you wait." That's asynchronous code.</p>
<h2><strong>Asynchronous Means Not to Wait</strong></h2>
<p>When you make something asynchronous, you're telling JavaScript to kick it off and move on. The rest of your code keeps running. When the slow thing finishes, it comes back and delivers its result.</p>
<p>The classic real-world version: you order food at a restaurant. The waiter takes your order, goes to the kitchen, and comes back later. You don't sit frozen at the table until your food is cooked. You talk to your friends. You look at your phone. The kitchen is doing its thing in the background.</p>
<pre><code class="language-javascript">console.log("Placed the order");     // runs immediately

setTimeout(() =&gt; {
  console.log("Food is ready!");    // runs after 2 seconds
}, 2000);

console.log("Talking to friends");   // runs immediately, doesn't wait

// Output:
// Placed the order
// Talking to friends
// Food is ready!    ( arrives 2 seconds later )
</code></pre>
<p>"Talking to friends" printed before "Food is ready!" even though it's written after the <code>setTimeout</code>. That's asynchronous behavior. JavaScript didn't wait at the timer. It moved on, and the timer delivered its result later when it was done.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/7e1e9fd6-1664-453b-8077-ede38b67c8a8.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>The Event Loop</strong></h2>
<p>There's a piece of JavaScript's internals called the <strong>event loop</strong>. It's not something you write. It just runs constantly in the background, checking one thing: "is the main thread free? Is there anything waiting to run?"</p>
<p>When you kick off a timer, an API call, or a file read, JavaScript hands it off to the browser (or Node.js) and moves on. When that thing finishes, the result gets placed in a queue. The event loop watches that queue. The moment the main thread goes idle, the event loop pulls the next item out of the queue and runs it.</p>
<p>This is how JavaScript stays responsive even though it only has one thread. It doesn't actually do two things simultaneously. It does things quickly enough, and defers slow things, that it feels simultaneous.</p>
<h2><strong>Three Ways to Write Async Code</strong></h2>
<p>JavaScript has gone through a few different syntaxes for dealing with async code. You'll see all three in real codebases, so it's worth knowing what each one looks like.</p>
<p><strong>Callbacks</strong> were first. You pass a function to be called when something finishes. They work, but nesting them for multiple sequential steps becomes a mess fast.</p>
<pre><code class="language-javascript">// old way
fetchUser(1, function(user) {
  fetchPosts(user.id, function(posts) {
    fetchComments(posts[0].id, function(comments) {
      // three levels deep. now imagine five or six.
      console.log(comments);
    });
  });
});
</code></pre>
<p>This staircase pattern is called <strong>callback hell</strong>. It's what production code actually looked like before Promises.</p>
<p><strong>Promises</strong> cleaned this up. A promise is an object that represents a value that isn't ready yet. You chain <code>.then()</code> calls instead of nesting functions.</p>
<pre><code class="language-javascript">// Promise
fetchUser(1)
  .then(user    =&gt; fetchPosts(user.id))
  .then(posts   =&gt; fetchComments(posts[0].id))
  .then(comments =&gt; console.log(comments))
  .catch(err     =&gt; console.error(err));  // one place to handle errors
</code></pre>
<p><strong>async/await</strong> is the current standard. It's built on Promises, but it lets you write async code so it reads like synchronous code. The <code>await</code> keyword pauses <em>the current function</em> (not the whole thread) until the promise resolves.</p>
<pre><code class="language-javascript">// async-await
async function loadComments() {
  try {
    const user     = await fetchUser(1);
    const posts    = await fetchPosts(user.id);
    const comments = await fetchComments(posts[0].id);
    console.log(comments);
  } catch (err) {
    console.error(err);
  }
}
</code></pre>
<p>Same three network calls. Same asynchronous behavior. Reads almost like synchronous code.</p>
<p><strong>Callback and Promises</strong></p>
<ul>
<li><p>Callbacks looks simple at first, but gets into callback hell</p>
</li>
<li><p>Promises has flat chains, and cleaner error handling</p>
</li>
<li><p>Still reads like async code, harder to follow when promise chaining gets involved</p>
</li>
</ul>
<p><strong>async / await</strong></p>
<ul>
<li><p>Syntactic sugar of Promises</p>
</li>
<li><p>Reads top-to-bottom, like synchronous code</p>
</li>
<li><p>try/catch handles errors the normal way</p>
</li>
</ul>
<h2><strong>Fetching a User Profile</strong></h2>
<p>Here's what the async pattern looks like when something actually goes wrong. User1 loads the page. The app fetches their profile from an API. While that's happening, the rest of the UI stays live. When the data comes back, the card renders. If the server returns an error, the UI handles it cleanly.</p>
<pre><code class="language-javascript">// users.js
export async function fetchUserProfile(userId) { 
const res = await fetch(`/api/users/${userId}`); 
if (!res.ok) throw new Error(Status ${res.status}); 
return res.json(); 
}
</code></pre>
<pre><code class="language-javascript">// profile.js
import { fetchUserProfile } from '../api/users.js';

async function renderProfile(userId) {
  const card = document.getElementById("profile");
  card.innerHTML = "Loading...";   

  try {
    const user = await fetchUserProfile(userId);
    card.innerHTML = `
      &lt;h2&gt;${user.name}&lt;/h2&gt;
      &lt;p&gt;${user.email}&lt;/p&gt;
    `;
  } catch (err) {
    card.innerHTML = "Could not load profile.";
    console.error(err);
  }
}

renderProfile(42);
</code></pre>
<p>The <code>"Loading..."</code> line on line four is the important part. It runs synchronously, before the await. The user sees something immediately. The network call happens in the background.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/3f63f59b-9c4f-4e2b-a552-8e543df5af70.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>What You Actually Get From Async Code</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b514985e-929c-4f19-81ec-954547cb4131.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS/Introducing">MDN Web Docs : Introducing asynchronous JavaScript</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">MDN Web Docs : async function</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[String Methods]]></title><description><![CDATA[When you write "hello" in JavaScript, you're not just storing letters. You get an object with a bunch of methods sitting on it. Things like .toUpperCase(), .includes(), .slice(). You can call them imm]]></description><link>https://blog.saumyagrawal.in/string-methods</link><guid isPermaLink="true">https://blog.saumyagrawal.in/string-methods</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Mon, 23 Mar 2026 17:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/606c201a-8340-452d-b3d4-ebd007f1450f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you write <code>"hello"</code> in JavaScript, you're not just storing letters. You get an object with a bunch of methods sitting on it. Things like <code>.toUpperCase()</code>, <code>.includes()</code>, <code>.slice()</code>. You can call them immediately, without any setup.</p>
<p>Most beginners use these without thinking about what's happening underneath. That works fine until you're in an interview and someone asks you to implement <code>.includes()</code> yourself. Or until you hit a weird edge case and don't understand why the built-in method behaved the way it did.</p>
<blockquote>
<p>Strings in JavaScript are <strong>immutable</strong>. No string method changes the original. Every method returns a new value. If you don't capture that return value, it's gone.</p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/fe24c639-f43d-4349-b025-43c4c2422a45.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>How Built-In Methods Actually Work</strong></h2>
<p>JavaScript loops through characters, checks conditions, and builds a result. <code>.includes()</code> is a loop that returns <code>true</code> the moment it finds a match. <code>.toUpperCase()</code> walks every character and shifts it to uppercase using Unicode. <code>.trim()</code> scans from both ends and stops when it hits a non-space character.</p>
<p>When you understand that, weird behavior starts making sense. Why does <code>.indexOf()</code> return <code>-1</code> when it finds nothing? Because it's returning the position of the match, and there's no position that means "not found" other than an impossible one. Why does <code>.slice(-3)</code> count from the end? Because the method is designed to accept negative indices as an offset from the string's length.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a61b4832-a74d-4d37-989a-de51303bacf5.png" alt="" style="display:block;margin:0 auto" />

<p>This matters because it changes how you read code. When you see <code>.slice(6)</code> you know it starts a loop at index 6. When you see <code>.replace(/\s+/g, " ")</code> you know it runs through the string once replacing every cluster of whitespace. They're loops with return values.</p>
<h2><strong>The Methods You'll Actually Use</strong></h2>
<p>There are 30-something string methods in JavaScript. Most of them you'll call once in your life. A handful you'll use every day. Here are the ones that matter.</p>
<p><strong>Slicing and Searching</strong></p>
<pre><code class="language-javascript">
const s = "hello world";

// slice(start, end): end is exclusive. negative counts from the back.
s.slice(0, 5)     // "hello"
s.slice(6)        // "world"
s.slice(-5)       // "world" — 5 from the end

// indexOf: returns position or -1. case sensitive.
s.indexOf("world")  // 6
s.indexOf("xyz")    // -1

// includes: just want true/false? use this instead of indexOf.
s.includes("world") // true

// startsWith / endsWith
s.startsWith("hello") // true
s.endsWith("world")   // true
</code></pre>
<p><strong>Transforming</strong></p>
<pre><code class="language-javascript">const s = "  Hello World  ";

// Case
s.toUpperCase()  // "  HELLO WORLD  "
s.toLowerCase()  // "  hello world  "

// Trim whitespace: trim() does both ends, trimStart/trimEnd do one side
s.trim()         // "Hello World"
s.trimStart()    // "Hello World  "

// Replace: replace() only hits the first match. replaceAll() gets every one.
"aabbcc".replace("b", "x")    // "axbcc" — only first b
"aabbcc".replaceAll("b", "x") // "aaxxcc" — both

// Split and join: two sides of the same coin
"a,b,c".split(",")         // ["a","b","c"]
["a","b","c"].join("-")     // "a-b-c"

// Padding: useful for formatting numbers and IDs
"7".padStart(3, "0")  // "007"
"7".padEnd(3, ".")    // "7.."

// Repeat
"na".repeat(4)  // "nananana"
</code></pre>
<p>One thing that trips beginners: <code>.replace()</code> only replaces the <strong>first</strong> match. If you want all of them, use <code>.replaceAll()</code> or pass a regex with the <code>g</code> flag: <code>.replace(/b/g, "x")</code>.</p>
<h2>Polyfills: When The String Methods are Missing</h2>
<p>A polyfill is just a manual implementation of a built-in method. You write it so an environment that doesn't have it can still run code that uses it. Older browsers are the typical reason, but polyfills show up in interviews for a different reason: if you can write one, you actually understand what the method does.</p>
<p>Let's see the example for trim polyfill:</p>
<pre><code class="language-javascript">function myTrim(str) {
  let start = 0;
  let end   = str.length - 1;

  // walk inward from both sides until we hit a non-space
  while (start &lt;= end &amp;&amp; str[start] === " ") start++;
  while (end   &gt;= start &amp;&amp; str[end]   === " ") end--;

  return str.slice(start, end + 1);
}

myTrim("  hello  ")  // "hello"
myTrim("   ")         // ""
</code></pre>
<p>Here is the implementation of includes through polyfill:</p>
<pre><code class="language-javascript">// .includes(searchStr, fromIndex)
function myIncludes(str, search, from = 0) {
  // normalize negative fromIndex
  const start = from &lt; 0
    ? Math.max(0, str.length + from)
    : from;

  for (let i = start; i &lt;= str.length - search.length; i++) {
    if (str.slice(i, i + search.length) === search) {
      return true;
    }
  }
  return false;
}

myIncludes("hello world", "world")  // true
myIncludes("hello world", "xyz")    // false
</code></pre>
<h2>The Hiccup in Interview</h2>
<p>Interviews like string problems because they test whether you can think character-by-character. You can't memorize your way through these. You need to actually understand how strings are structured.</p>
<p>Here are four problems that come up repeatedly. Each one builds on a concept from the methods above</p>
<p><strong>Reverse a String</strong></p>
<pre><code class="language-javascript">// split into chars, reverse the array, join back.
function reverseString(str) {
  return str.split("").reverse().join("");
}

// without array methods 
function reverseManual(str) {
  let result = "";
  for (let i = str.length - 1; i &gt;= 0; i--) {
    result += str[i];
  }
  return result;
}

reverseString("hello")  // "olleh"
</code></pre>
<p><strong>String is a Palindrome</strong></p>
<pre><code class="language-javascript">// A string that reads the same forward and backward.
function isPalindrome(str) {
  const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, "");
  return cleaned === cleaned.split("").reverse().join("");
}

isPalindrome("racecar")          // true
isPalindrome("A man a plan a canal Panama") // true (after cleanup)
isPalindrome("hello")             // false
</code></pre>
<p><strong>Count Occurrences of a Character</strong></p>
<pre><code class="language-javascript">function countChar(str, char) {
  let count = 0;
  for (const c of str) {
    if (c === char) count++;
  }
  return count;
}

// One-liner using split
const countChar2 = (str, char) =&gt; str.split(char).length - 1;

countChar("hello", "l")   // 2
</code></pre>
<p><strong>Capitalize First Letter of Each Word</strong></p>
<pre><code class="language-javascript">function titleCase(str) {
  return str
    .split(" ")
    .map(word =&gt; word[0].toUpperCase() + word.slice(1).toLowerCase())
    .join(" ");
}

titleCase("the quick brown fox")  // "The Quick Brown Fox"
</code></pre>
<h2><strong>Why Built-In Behavior Matters</strong></h2>
<p>JavaScript's string methods are not always consistent in how they handle edge cases. Knowing what to expect saves you a debugging session at the wrong moment.</p>
<p><strong>The Gotchas</strong></p>
<ul>
<li><p><code>"".split("x")</code> returns <code>[""]</code>, not <code>[]</code></p>
</li>
<li><p><code>.indexOf()</code> is case-sensitive. <code>"Hello".indexOf("h")</code> is <code>-1</code></p>
</li>
<li><p><code>.slice(2, 0)</code> returns <code>""</code> . End before start is empty</p>
</li>
<li><p><code>.replace()</code> only replaces the first match without <code>/g</code></p>
</li>
<li><p><code>typeof "hello"</code> is <code>"string"</code>, not <code>"object"</code></p>
</li>
</ul>
<p><strong>The Knowledge for the Long Run</strong></p>
<ul>
<li><p>Template literals avoid a lot of <code>.replace()</code> calls</p>
</li>
<li><p><code>.at(-1)</code> gets the last character without <code>.length - 1</code></p>
</li>
<li><p>Chaining works: <code>.trim().toLowerCase().split(",")</code></p>
</li>
<li><p><code>.split("")</code> breaks a string into individual characters</p>
</li>
<li><p>Strings are iterable: <code>for (const c of str)</code> works</p>
</li>
</ul>
<pre><code class="language-javascript">// split on empty string : array of individual chars
"abc".split("")    // ["a","b","c"]
"".split("")       // []  | empty string, empty array
"".split("x")      // [""]  | one empty string element. catches people out.

// indexOf vs includes
"hello".indexOf("H")   // -1 | case sensitive
"hello".includes("H")  // false | also case sensitive

// slice with inverted indices
"hello".slice(3, 1)   // "" | start after end. empty
"hello".slice(-2)     // "lo" | last 2 chars
</code></pre>
<h2><strong>What You Actually Get From Understanding This</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a378c87d-0229-4500-ac87-0beef259c6fd.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">MDN Web Docs : String</a></p>
</li>
<li><p><a href="https://javascript.info/string">JavaScript.info : Strings</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[JavaScript Modules]]></title><description><![CDATA[Here's a situation that happens on basically every team that doesn't use modules. Aditya is writing the auth logic, Saumya is building the user profile page, and Manas is working on the cart. They're ]]></description><link>https://blog.saumyagrawal.in/javascript-modules</link><guid isPermaLink="true">https://blog.saumyagrawal.in/javascript-modules</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[modules]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Sun, 22 Mar 2026 19:57:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/3098c94f-cee8-4a8a-a2bf-85c6a4a8357b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here's a situation that happens on basically every team that doesn't use modules. Aditya is writing the auth logic, Saumya is building the user profile page, and Manas is working on the cart. They're all on the same app. Without modules, everyone's code goes into one file: <code>app.js</code>. It works fine at first. Then it's 600 lines. Then 1,400. At 3,000 lines, people start writing new code at the bottom just to avoid scrolling.</p>
<p>But line count is not actually the problem. The problem is that all that code shares one global scope. Aditya declares <code>var user</code> for his login flow. Saumya also declares <code>var user</code> for the profile component. JavaScript doesn't throw an error. It just replaces one with the other, silently, based on load order. Aditya's login function now reads Manas' cart user. No warning. You find out at 2am when something explodes in production.</p>
<p>This isn't a bug in anyone's code. It's what happens when three people share a single room with no walls. Any variable can reach any other variable. You lose track fast.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/3159c877-7c9f-45d4-9e88-919a1afe7278.png" alt="" style="display:block;margin:0 auto" />

<pre><code class="language-javascript">// Aditya's auth section 
var user = "Aditya";

// Saumya's profile section overwrites Aditya's user, no error 
var user = "Saumya";

// Manas' cart section overwrites Saumya's. login() now gets this. 
var user = "Manas"; function addToCart() { /* ... */ }

// Good luck figuring out which user you're reading on line 847.
</code></pre>
<h2><strong>What is a Module ?</strong></h2>
<p>A module is just a file that owns its own scope. Whatever you write in it stays in it. Other files cannot read your variables, call your functions, or accidentally overwrite anything inside unless you specifically open a door with <code>export</code>. And if another file wants something, it has to ask with <code>import</code>.</p>
<p>That's the whole model. JavaScript has had this built in since 2015. No extra tools. Two keywords. Each file becomes its own room with a lock on the door.</p>
<p>You end up with small files that each own their own piece of logic, and connect to each other through the specific things they choose to share. When something breaks, you know exactly whose room to check.</p>
<h2><strong>Exporting: What You Choose to Share</strong></h2>
<p>By default, nothing leaves a module file. You have to opt things out with <code>export</code>. There are two ways to do it and they work differently: named exports and default exports.</p>
<p>Named exports let you export multiple things from one file. You put <code>export</code> in front of each one, and they each keep their name. Default exports are for when the file is really just one thing, you get one per file, and whoever imports it can name it whatever they want locally.</p>
<pre><code class="language-javascript">// Each one is named and exported separately
export function add(a, b)      { return a + b; }
export function multiply(a, b) { return a * b; }
export const PI = 3.14159;
</code></pre>
<pre><code class="language-javascript">// This file's whole job is logging. One thing, one export.
export default function log(msg) {
  const ts = new Date().toLocaleTimeString();
  console.log(`[\({ts}] \){msg}`);
}
</code></pre>
<h2><strong>Importing: Asking For What You Need</strong></h2>
<p>Imports go at the top of the file, always. JavaScript reads them all first before executing anything, it builds a map of what depends on what before running a single line of your logic.</p>
<p>Named imports use curly braces and the exact name. Default imports don't need curly braces, and you can name them whatever makes sense locally. You can also rename a named import with <code>as</code> if it clashes with something.</p>
<pre><code class="language-javascript">// Named import, must match the exported name exactly
import { add, multiply, PI } from './utils/math.js';

// Default import, call it whatever you like locally
import log from './utils/logger.js';

// Rename a named import to avoid a local conflict
import { add as addNums } from './utils/math.js';

log(`2 + 3 = ${add(2, 3)}`);   // [10:32:01] 2 + 3 = 5
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0e66f27c-53e9-4b02-aec9-c39cadfac630.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Named vs Default</strong></h2>
<p>Named and default exports look similar but they behave differently on the import side. Named imports need curly braces and the exact name. Default imports take no curly braces and you pick the local name yourself. Mixing them up is the most common beginner mistake and the error message is not always obvious.</p>
<p>The rule most teams use: if a file exports multiple things, use named. If a file is about one single thing a React component, a class, a config factory use default. That split tends to make codebases easier to read at a glance.</p>
<table>
<thead>
<tr>
<th>Named Exports</th>
<th>Default Exports</th>
</tr>
</thead>
<tbody><tr>
<td>Curly braces on import</td>
<td>No curly braces</td>
</tr>
<tr>
<td>Name must match exactly (or use <code>as</code>)</td>
<td>Caller picks any local name</td>
</tr>
<tr>
<td>Many per file, good for utility collections</td>
<td>One per file, for the main thing</td>
</tr>
<tr>
<td>Tree-shakeable: bundlers drop what you don't import</td>
<td>Not tree-shakeable, whole thing is imported</td>
</tr>
</tbody></table>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/d8097813-fe73-4470-a627-1e75357ffba7.png" alt="" style="display:block;margin:0 auto" />

<p>If bundle size matters to your project, prefer named exports for utility code. Bundlers like Vite and Rollup can drop named exports nobody imports, they can't do that with defaults, since the whole default is treated as one unit.</p>
<h2><strong>How Files Connect to Each Other</strong></h2>
<p>Once you split code into modules, a structure forms on its own. Utility files get imported by feature files. Feature files get imported by the entry point. Nothing in a utility knows anything about the feature files using it. Nothing in the entry point knows how the features are implemented internally.</p>
<p>When a bug shows up, you trace the arrow. Something wrong in the cart? Start at cart.js. It imports from api.js and utils/format.js, so the bug is in one of those three places, not scattered across 3,000 lines of a single file.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/506aa4e3-377c-4870-8134-b03f2c00f07c.png" alt="" style="display:block;margin:0 auto" />

<h2>Isolation is Key</h2>
<p>Here's a user card feature spread across four files. Read it and notice what each file does <em>not</em> know. <code>utils/format.js</code> has no idea there's a user object involved, it just handles strings. <code>api/users.js</code> knows nothing about how the card looks. <code>main.js</code> has two lines and still renders everything correctly.</p>
<pre><code class="language-javascript">// utils/format.js
// only job is formatting
export function formatName(user) {
  return `\({user.firstName} \){user.lastName}`;
}
export function formatDate(str) {
  return new Date(str).toLocaleDateString('en-IN');
}
</code></pre>
<pre><code class="language-javascript">// api/users.js
// only fetch a user
export async function fetchUser(id) {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error("User not found");
  return res.json();
}
</code></pre>
<pre><code class="language-javascript">// components/userCard.js
import { fetchUser } from '../api/users.js';
import { formatName, formatDate } from '../utils/format.js';

// just builds a card
export default async function renderUserCard(userId) {
  const user = await fetchUser(userId);
  return `
    &lt;div class="card"&gt;
      &lt;h2&gt;${formatName(user)}&lt;/h2&gt;
      &lt;p&gt;Joined: ${formatDate(user.createdAt)}&lt;/p&gt;
    &lt;/div&gt;`;
}
</code></pre>
<pre><code class="language-javascript">// main.js
import renderUserCard from './components/userCard.js';

// responsible to render things correctly
document.getElementById("app").innerHTML = await renderUserCard(42);
</code></pre>
<p>If the API changes how it returns user data, you update <code>api/users.js</code>. If the date format needs to change, you update <code>utils/format.js</code>. Neither change touches the other files. That's the payoff.</p>
<h2>The Objective of This Approach</h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/274c0fa2-3703-4373-8305-a968d76fef89.png" alt="" style="display:block;margin:0 auto" />]]></content:encoded></item><item><title><![CDATA[The Developer's Guide to Flattening Arrays in JavaScript]]></title><description><![CDATA[Let us see the problem first. Imagine you fetched user data from two API pages. Page one gives you [1, 2, 3]. Page two gives you [4, 5, 6]. You shove them both into an array to combine them, and you g]]></description><link>https://blog.saumyagrawal.in/the-developer-s-guide-to-flattening-arrays-in-javascript</link><guid isPermaLink="true">https://blog.saumyagrawal.in/the-developer-s-guide-to-flattening-arrays-in-javascript</guid><category><![CDATA[array]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Sun, 22 Mar 2026 18:05:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/ff879c77-6813-4279-80a9-82a2c03fc391.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let us see the problem first. Imagine you fetched user data from two API pages. Page one gives you <code>[1, 2, 3]</code>. Page two gives you <code>[4, 5, 6]</code>. You shove them both into an array to combine them, and you get this:</p>
<pre><code class="language-javascript">const page1 = [1, 2, 3];
const page2 = [4, 5, 6];

const combined = [page1, page2];
console.log(combined);
// → [[1, 2, 3], [4, 5, 6]]  | not what you wanted

// You wanted [1, 2, 3, 4, 5, 6]
// What you got is an array of arrays
</code></pre>
<p>That outer wrapper is the problem. You don't want to loop over two arrays, you want one flat list. That's flattening. You're collapsing the layers down into a single level so you can actually work with the data.</p>
<p>This happens more than you'd think. APIs send paginated responses. A <code>.map()</code> that returns an array per item gives you nested output. Form inputs grouped by section produce grouped values. The data structure that made sense to build becomes inconvenient the moment you need to use it.</p>
<hr />
<h2><strong>What Nested Actually Looks Like</strong></h2>
<p>Before getting into solutions, it's worth seeing exactly what we're dealing with. An array can nest multiple levels deep, each layer adds another set of brackets around the values inside.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/be65f099-8a21-4533-b47f-fed8a5bc75a4.png" alt="" style="display:block;margin:0 auto" />

<p>The number of layers is called depth. Depth 1 means one array wrapped inside another. Depth 2 means arrays inside arrays inside the outer array. When you flatten, you're deciding how many of those layers to remove.</p>
<h2><strong>Just Use</strong> <code>.flat()</code></h2>
<p>ES2019 added <code>Array.prototype.flat()</code> and honestly it just works. Pass a depth number, or pass <code>Infinity</code> to collapse every layer no matter how deep. Most of the time this is all you need.</p>
<pre><code class="language-javascript">const nested = [1, [2, 3], [4, [5, 6]]];

nested.flat();
// [1, 2, 3, 4, [5, 6]]   default depth is 1

nested.flat(2);
// [1, 2, 3, 4, 5, 6]     removes two levels

nested.flat(Infinity);
// [1, 2, 3, 4, 5, 6]     flattens everything
</code></pre>
<p>There's also <code>.flatMap()</code>, which runs a map and flattens one level in one pass. It's faster than calling <code>.map()</code> then <code>.flat(1)</code> separately, and you'll use it whenever your mapping function returns an array per element.</p>
<pre><code class="language-javascript">const sentences = ["hello world", "foo bar"];

// .map() gives you nested arrays
sentences.map(s =&gt; s.split(" "));
// [["hello","world"], ["foo","bar"]]

// .flatMap() flattens that one level automatically
sentences.flatMap(s =&gt; s.split(" "));
// ["hello", "world", "foo", "bar"]
</code></pre>
<blockquote>
<p><strong>One thing to watch:</strong> <code>.flat()</code> skips empty slots in arrays , things like <code>[1, , 3]</code>. That's usually what you want, but if you're working with sparse arrays intentionally, keep it in mind.</p>
</blockquote>
<h2><strong>Before</strong> <code>.flat()</code> <strong>Came to Existence</strong></h2>
<p>This might be a favourite topic of few interviewers out there, to flatten the array without the inbuilt method. The classic approach uses <code>reduce</code> with recursion. For each element, check if it's an array. If it is, flatten it recursively and concat the result. If it isn't, add it directly.</p>
<pre><code class="language-javascript">function flatten(arr) {
  return arr.reduce((acc, val) =&gt; 
    Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), 
  []);
}

flatten([1, [2, [3, [4, [5]]]]]);
// [1, 2, 3, 4, 5]   
// works at any depth
</code></pre>
<p>This handles any depth without you specifying it. The recursion bottoms out naturally when there are no more arrays to unwrap.</p>
<p>For the depth-controlled version, that's a small addition:</p>
<pre><code class="language-javascript">const flattenByDepth = (arr, depth = 1) =&gt; 
  depth &gt; 0 ? arr.reduce((acc, val) =&gt; 
    acc.concat(Array.isArray(val) ? flattenByDepth(val, depth - 1) : val), 
  []) : arr.slice();

flattenDepth([1, [2, [3, [4]]]], 2);
// [1, 2, 3, [4]]  
// stopped at depth 2
</code></pre>
<p>Nested arrays happen. APIs return batches, maps produce nested output, data gets grouped before it gets used. Flattening is just the act of removing those layers. <em>.flat(Infinity)</em> handles it in one call. The recursive <code>reduce</code> version is what interviewers want you to derive. And once you've written flatten a few times, the same mental model carries over to nested objects, tree traversal, and anything else where data lives at multiple depths.</p>
<p>The depth question is the one to keep in mind. Most bugs with flattening come from not removing enough layers, or accidentally removing too many. Know what's in your data before you pick your depth.</p>
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">Array : flat</a>()</p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap">Array.prototype.flatMap()</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Template Literals]]></title><description><![CDATA[At some point you wrote something like this. You had a user's name, a score, and a message to display. So you built the string the way everyone learns first: with +.
var name = "Priya";
var score = 42]]></description><link>https://blog.saumyagrawal.in/template-literals</link><guid isPermaLink="true">https://blog.saumyagrawal.in/template-literals</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Sun, 22 Mar 2026 06:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/c7760a62-fe85-4e9d-8382-1aa60ceb6cb3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At some point you wrote something like this. You had a user's name, a score, and a message to display. So you built the string the way everyone learns first: with <code>+</code>.</p>
<pre><code class="language-javascript">var name = "Priya";
var score = 42;

var msg = "Hello, " + name + "! Your score is " + score + ".";

// Hello, Priya! Your score is 42.
// Six pieces. Four operators. Two sets of quotes you can barely track.
</code></pre>
<p>It works. Nobody's disputing that. But read it again. Your eyes have to jump between strings and variables and operators to figure out what the final output looks like. Now imagine doing that with a URL, a multi-line HTML snippet, or anything where the variable is buried in the middle of actual sentence structure. The longer the string, the worse it gets.</p>
<p>Template literals fix this. They've been in JavaScript since 2015. If you're not using them, you're doing more work than you need to.</p>
<h2><strong>The Syntax, Plainly</strong></h2>
<p>Two changes. You swap regular quotes for backticks. And anywhere you'd previously close the string, concatenate, and reopen it, you write <code>${ }</code> instead.</p>
<pre><code class="language-javascript">const name = "Priya";
const score = 42;

const msg = `Hello, \({name}! Your score is \){score}.`;

// Hello, Priya! Your score is 42.
// Same output. You can actually read what it says.
</code></pre>
<p>The backtick key is in the top-left of most keyboards, above Tab. That's the only new character involved. Everything inside <code>${ }</code> is treated as JavaScript, so the value gets evaluated and dropped into the string wherever you put it.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/43fc3180-6497-4ae5-a5de-2a3ce15fc07f.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>The Actual Difference</strong></h2>
<p>The clearest way to see the improvement is to put both approaches next to each other doing the same job. Not a toy example. Something you'd actually write.</p>
<pre><code class="language-javascript">// String Concatenation
const user = "Riya";
const item = "headphones";
const price = 1299;
const currency = "INR";

const receipt = "Hi " + user + ", you bought " + item +
  " for " + currency + " " + price + "!";
// count the quotes. count the + signs. now imagine finding the bug.
</code></pre>
<pre><code class="language-javascript">// Template Literal
const user = "Riya";
const item = "headphones";
const price = 1299;
const currency = "INR";

const receipt = `Hi \({user}, you bought \){item} for \({currency} \){price}!`;
// read like a sentence. edit like a sentence. done.
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0d895f01-00b8-43a6-b364-b72c7504b069.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Expressions, Not Just Variables</strong></h2>
<p>The <code>${ }</code> slot takes any valid JavaScript expression. Not just variable names. A variable is just the simplest case. You can put math, function calls, ternaries, method calls, comparisons, if JavaScript can evaluate it to a value, it goes in there.</p>
<pre><code class="language-javascript">const a = 4; const b = 7;

// Math directly in the string 
const sum = \({a} + \){b} = ${a + b}; // "4 + 7 = 11"

// Function call 
const shout = Hello, ${"priya".toUpperCase()}!; // "Hello, PRIYA!"

// Ternary: conditional logic inside the string 
const stock = 0; const label = Item is ${stock &gt; 0 ? "available" : "out of stock"}.; // "Item is out of stock."
</code></pre>
<h2><strong>Multi-Line Strings</strong></h2>
<p>This is where the old way falls apart completely. Building a multi-line string with concatenation means either pasting everything on one long line or escaping newlines with <code>\n</code>. Neither approach matches what the output actually looks like.</p>
<pre><code class="language-javascript">// String
const html = "&lt;div class='card'&gt;\n" +
  "  &lt;h2&gt;" + name + "&lt;/h2&gt;\n" +
  "  &lt;p&gt;" + bio + "&lt;/p&gt;\n" +
  "&lt;/div&gt;";

// Template Literals
const name = "Riya";
const bio = "Frontend developer. Loves TypeScript.";

const html = `
  &lt;div class="card"&gt;
    &lt;h2&gt;${name}&lt;/h2&gt;
    &lt;p&gt;${bio}&lt;/p&gt;
  &lt;/div&gt;
`;

// the indentation in the code matches the indentation in the output.
// what you see is what you get.
</code></pre>
<p>The line breaks are real. The whitespace is real. You press Enter inside the backticks and it's in the string. No <code>\n</code>. No squinting at escape characters.</p>
<p>This matters most when building HTML fragments, SQL queries, email bodies, or any block of text that has real structure. You can format the string the way the output should look, and the two stay in sync.</p>
<h2><strong>Where You'll Actually Use This</strong></h2>
<p>Template literals show up in the same places strings show up. But there are a few spots where they make an especially big difference.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/2a2a604f-a12d-4cd8-ae91-ad1a86359f7b.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">Template literals</a> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">: MDN Web Docs</a></p>
</li>
<li><p><a href="https://tc39.es/ecma262/#sec-template-literals">ECMAScript 2015 Specification Template Literals</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The this Keyword]]></title><description><![CDATA[At some point you will write a method on an object, call it directly and it works fine, then pass it somewhere as a callback and it completely falls apart. this.name comes back undefined. The code loo]]></description><link>https://blog.saumyagrawal.in/the-this-keyword</link><guid isPermaLink="true">https://blog.saumyagrawal.in/the-this-keyword</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[this keyword]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Sat, 21 Mar 2026 05:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/25b986e4-d62d-4d9f-8941-45e8d9b03919.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At some point you will write a method on an object, call it directly and it works fine, then pass it somewhere as a callback and it completely falls apart. <a href="http://this.name"><code>this.name</code></a> comes back <code>undefined</code>. The code looks exactly the same to you. The error message is no help at all.</p>
<p>That is <code>this</code> doing something you did not expect, because nobody explained the one idea that makes all of its behavior obvious. This post is built around that idea. Everything else follows from it.</p>
<h2><strong>What</strong> <code>this</code> <strong>Represents</strong></h2>
<p><code>this</code> is the object that called the function. Not where the function was written, not where it lives in the file. Who called it, right now, at this moment.</p>
<p>Think of a customer service line. When someone calls in, the rep picks up and sees the caller's name on screen. That display changes every time a different person rings. The phone line is the function. The name on the display is <code>this</code>.</p>
<p>Here is the simplest version of that in code:</p>
<pre><code class="language-javascript">function greet() {
  console.log("Hello, I am " + this.name);
}

const user  = { name: "Rohan", greet };
const admin = { name: "Priya", greet };

user.greet();   // user called it: this = user
admin.greet();  // admin called it: this = admin

// OUTPUT:
// Hello, I am Rohan
// Hello, I am Priya
</code></pre>
<p>One function, written once. The dot before the method call is your clue every time: whatever is on the left of that dot when the function runs is <code>this</code>. Keep that in mind as you read the rest of this post.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a106176d-0b7a-4190-9f16-17ff15b33af2.png" alt="" style="display:block;margin:0 auto" />

<h2><code>this</code> <strong>In The Global Context</strong></h2>
<p>Before any functions or objects, there is already a <code>this</code>. At the very top of a script, outside everything else, it points to the global object. In a browser that is <code>window</code>.</p>
<pre><code class="language-javascript">// Browser
console.log(this);            // Window {…}
console.log(this === window); // true
</code></pre>
<p>In Node.js the story is slightly different. At the top of a CommonJS file, <code>this</code> is the module's <code>exports</code> object, not Node's global. It looks like an empty object by default because nothing has been exported yet.</p>
<pre><code class="language-javascript">// Node.JS
console.log(this);                   // {}
console.log(this === global);         // false
console.log(this === module.exports); // true
</code></pre>
<p>You will almost never use the global <code>this</code> on purpose. What matters here is knowing it exists so you are not confused when it shows up unexpectedly in the console or in an error message.</p>
<h2><code>this</code> <strong>Inside Objects</strong></h2>
<p>When a function is called as a method of an object, <code>this</code> is that object. This is the case that feels the most natural and the one that matches what beginners usually expect. The object called the method, so the object is <code>this</code>.</p>
<pre><code class="language-javascript">const player = {
  name:  "Rohan",
  score: 1400,
  showScore() {
    console.log(this.name + " has " + this.score + " points");
  }
};

player.showScore();  // player is on the left: this = player

// OUTPUT:
// Rohan has 1400 points
</code></pre>
<p>Swap the caller, swap <code>this</code>. The same function attached to two different objects gives two different results:</p>
<pre><code class="language-javascript">const playerOne = { name: "Rohan", score: 1400 };
const playerTwo = { name: "Divya", score: 2100 };

function showScore() {
  console.log(this.name + " has " + this.score + " points");
}

playerOne.show = showScore;
playerTwo.show = showScore;

playerOne.show();  // this = playerOne
playerTwo.show();  // this = playerTwo

// OUTPUT:
// Rohan has 1400 points
// Divya has 2100 points
</code></pre>
<h3>The Lost <code>this</code></h3>
<p>When you copy a method into a variable and call it, <code>this</code> is gone.</p>
<pre><code class="language-javascript">const player = {
  name: "Rohan",
  greet() {
    console.log("Hi, I am " + this.name);
  }
};

player.greet();          // `this` doesn't get lost

const fn = player.greet;  // just the function, no object
fn();                     // `this` gets lost

// OUTPUT:
// Hi, I am Rohan
// Hi, I am undefined
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/edc4ae0f-f2e7-4693-8d3e-1131ad165148.png" alt="" style="display:block;margin:0 auto" />

<p>Passing a method as a callback is the same problem. <code>setTimeout(player.greet, 1000)</code> hands over the function with no object. When it runs a second later, <code>this</code> is not <code>player</code>. This shows up constantly in real code.</p>
<h2><code>this</code> <strong>Inside Regular Functions</strong></h2>
<p>When a plain function is called with nothing on the left of the dot, <code>this</code> defaults to the global object. In strict mode it becomes <code>undefined</code> instead, which is actually safer because it fails loudly.</p>
<pre><code class="language-javascript">// Non-strict. this defaults to Window
function whoAmI() {
  console.log(this);
}

whoAmI(); // Window {…} in the browser

// Strict mode. this becomes undefined
"use strict";

function whoAmIStrict() {
  console.log(this);
}

whoAmIStrict(); // undefined
</code></pre>
<p>ES modules are strict by default. If your files use <code>import</code> and <code>export</code>, strict mode is already on. Most modern JavaScript projects run in modules, so you already have this without thinking about it.</p>
<h3><strong>Nested Functions Lose</strong> <code>this</code></h3>
<p>A regular function written inside a method does not inherit the method's <code>this</code>. It resets. The inner function is called as a plain function, so it gets the global default. Proximity in code has no effect; only the call site matters.</p>
<pre><code class="language-javascript">const game = {
  title: "Space Run",
  start() {
    console.log(this.title); // "Space Run". this = game

    function inner() {
      console.log(this.title); // undefined. this reset to Window
    }

    inner(); // called alone. no object on the left
  }
};

game.start();

// OUTPUT:
// Space Run
// undefined
</code></pre>
<p>The fix for this is arrow functions, which do not reset <code>this</code>.</p>
<h2><strong>How the Calling Context Changes</strong> <code>this</code></h2>
<p>Because <code>this</code> is set at call time, you can control it. JavaScript gives you three methods for this: <code>call</code>, <code>apply</code>, and <code>bind</code>.</p>
<h3><code>call()</code> <strong>and</strong> <code>apply()</code></h3>
<p>Both invoke the function immediately and let you specify the object to use as <code>this</code>. The difference is just how you pass other arguments. <code>call</code> takes them one by one. <code>apply</code> takes an array.</p>
<pre><code class="language-javascript">function introduce(city, sport) {
  console.log(this.name + " is from " + city + " and plays " + sport);
}

const maya = { name: "Maya" };
const leo  = { name: "Leo"  };

introduce.call(maya,  "Mumbai",  "cricket");     // args one by one
introduce.call(leo,   "Lisbon",  "football");
introduce.apply(maya, ["Mumbai", "cricket"]);   // args as array

// OUTPUT
// Maya is from Mumbai and plays cricket
// Leo is from Lisbon and plays football
// Maya is from Mumbai and plays cricket
</code></pre>
<h3><code>bind()</code></h3>
<p><code>bind</code> does not call the function. It returns a new copy with <code>this</code> permanently locked. That copy can be stored, passed around, and called later. It will always have the same <code>this</code>. This is the direct fix for the lost-this trap.</p>
<pre><code class="language-javascript">const player = {
  name: "Rohan",
  greet() {
    console.log("Hi, I am " + this.name);
  }
};

// Without bind, this is lost when passed as a callback
setTimeout(player.greet, 0);

// With bind, this is locked to player permanently
setTimeout(player.greet.bind(player), 0);

// OUTPUT:
// Hi, I am undefined
// Hi, I am Rohan
</code></pre>
<table>
<thead>
<tr>
<th>Method</th>
<th>Calls immediately</th>
<th>Args format</th>
<th>Returns</th>
</tr>
</thead>
<tbody><tr>
<td><strong>call(obj, a, b)</strong></td>
<td>Yes</td>
<td>one by one</td>
<td>result of the function</td>
</tr>
<tr>
<td><strong>apply(obj, [a, b])</strong></td>
<td>Yes</td>
<td>as an array</td>
<td>result of the function</td>
</tr>
<tr>
<td><strong>bind(obj, a, b)</strong></td>
<td>No</td>
<td>one by one</td>
<td>a new bound function</td>
</tr>
</tbody></table>
<h2><strong>Arrow Functions and</strong> <code>this</code></h2>
<p>Arrow functions do not have their own <code>this</code>. They look at the code around them at the time they were written and borrow whatever <code>this</code> was in that scope. That value never changes, regardless of how the arrow function gets called later.</p>
<p>This is exactly what fixes the nested function problem:</p>
<pre><code class="language-javascript">const game = {
  title: "Space Run",
  start() {
    // Regular function: this resets to Window inside here
    function inner() {
      console.log("regular: " + this.title);
    }

    // Arrow: borrows this from start(), which is game
    const innerArrow = () =&gt; {
      console.log("arrow: " + this.title);
    };

    inner();       
    innerArrow();  
  }
};

game.start();

// OUTPUT:
// regular: undefined
// arrow: Space Run
</code></pre>
<h3><strong>Where Arrow Functions Go Wrong</strong></h3>
<p>Arrow functions work great inside methods. Used as a method directly on an object, they break. The surrounding scope at write time is the global scope, so that is what gets borrowed.</p>
<pre><code class="language-javascript">// Arrow as method: breaks
const player = {
  name: "Rohan",
  greetArrow: () =&gt; {
    // borrows global scope
    console.log(this.name);
  }
};

player.greetArrow();
// undefined

// Regular as method: works
const player = {
  name: "Rohan",
  greetRegular() {
    // set at call time = player
    console.log(this.name);
  }
};

player.greetRegular();
// Rohan
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/8077df7f-5787-46ab-b77f-a78d983b5f71.png" alt="" style="display:block;margin:0 auto" />

<p>The practical rule: write methods on objects and classes with regular function syntax. Write callbacks inside those methods with arrow functions. That combination gives you the right <code>this</code> in both places without needing to think too hard about it.</p>
<h2><strong>All the Contexts at Once</strong></h2>
<p>Every case in this post comes from the same question: who is calling the function right now? Here is how each calling pattern maps to a result, and how to recognise which one you are looking at:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/15a65f7c-f923-4475-ad07-745196e08204.png" alt="" style="display:block;margin:0 auto" />

<p>When you are unsure which case applies, ask the same question every time: what is on the left of the dot when this function is called? If there is an object, that is <code>this</code>. If there is nothing, you are in the plain function case. If you used <code>call</code>, <code>apply</code>, or <code>bind</code>, you set it yourself. Arrow functions are the only exception, they ignore the call site entirely and use whatever was in scope when they were written.</p>
<p>Most of the bugs you will encounter are just the extracted-method case. A function that worked on an object, passed somewhere as a callback, lost its caller. <code>bind</code> fixes it. Arrow callbacks inside methods fix it too. Once you see what is happening, the fix is never complicated.</p>
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">MDN: this</a></p>
</li>
<li><p><a href="http://JavaScript.info">JavaScript.info</a><a href="https://javascript.info/object-methods">: Object methods and this</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">MDN: Function.prototype.bind()</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">MDN: Arrow function expression</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Spread & Rest]]></title><description><![CDATA[JavaScript has a syntax that looks identical in two different situations but means the opposite each time. Three dots: .... Depending on where you put them, they either expand something out or collect]]></description><link>https://blog.saumyagrawal.in/spread-rest</link><guid isPermaLink="true">https://blog.saumyagrawal.in/spread-rest</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[webdev]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Thu, 19 Mar 2026 14:36:00 GMT</pubDate><content:encoded><![CDATA[<p>JavaScript has a syntax that looks identical in two different situations but means the opposite each time. Three dots: <code>...</code>. Depending on where you put them, they either <strong>expand</strong> something out or <strong>collect</strong> things in.</p>
<p>When they expand, that's the spread operator. When they collect, that's the rest operator. Same three characters. Context decides which one you're looking at.</p>
<blockquote>
<p><strong>Spread pushes values out. Rest pulls values in.</strong></p>
</blockquote>
<h2><strong>Spread: Expanding Values Out</strong></h2>
<p>Spread takes something that contains multiple values, an array or an object, and unpacks them into individual pieces. Think of it as opening a box and laying everything out on the table.</p>
<p>The most common use is combining arrays. You have two lists and you want one. Before spread, you'd reach for <code>.concat()</code> or a loop. With spread, it's a single line.</p>
<pre><code class="language-javascript">const fruits = ["apple", "mango"];
const veggies = ["carrot", "spinach"];

// Spread both arrays into a new one
const groceries = [...fruits, ...veggies];
// ["apple", "mango", "carrot", "spinach"]

// You can mix in extra items anywhere
const fullCart = ["bread", ...fruits, "milk"];
// ["bread", "apple", "mango", "milk"]
</code></pre>
<p>Spread also makes copying arrays safe. In JavaScript, if you do <code>const b = a</code> with an array, both <code>b</code> and <code>a</code> point to the same array in memory. Change one, you change the other. Spread creates an actual independent copy.</p>
<pre><code class="language-javascript">const original = [1, 2, 3];

// This is NOT a copy, both point to the same array
const stillSame = original;
stillSame.push(4);
console.log(original); // [1, 2, 3, 4] 

// Spread makes a real copy
const safeCopy = [...original];
safeCopy.push(99);
console.log(original); // [1, 2, 3] 
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/554657f3-8d85-46a0-896e-5171e4612bcc.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Spread With Objects</strong></h2>
<p>Spread works on objects too, and this is where it becomes genuinely useful in everyday code. The pattern shows up constantly when you want to update one property without touching the rest of an object.</p>
<pre><code class="language-javascript">const defaultSettings = {
  theme: "dark",
  fontSize: 14,
  language: "en"
};

const userPrefs = { fontSize: 18, language: "hi" };

// Merge: user prefs override defaults
const finalSettings = { ...defaultSettings, ...userPrefs };
// { theme: "dark", fontSize: 18, language: "hi" }

// Update one field without mutating the original
const updated = { ...defaultSettings, theme: "light" };
// { theme: "light", fontSize: 14, language: "en" }
</code></pre>
<p>When keys clash, the last one wins. So <code>...defaultSettings</code> first, then <code>...userPrefs</code> means user preferences override the defaults. Flip the order and defaults would overwrite users. Position matters.</p>
<h2><strong>Rest: Collecting Values In</strong></h2>
<p>Rest does the opposite. Instead of spreading values out, it gathers them together. You use it in two places: function parameters and destructuring assignments.</p>
<p>In function parameters, rest collects all the arguments you didn't name explicitly into one array. This is how you write a function that accepts any number of arguments.</p>
<pre><code class="language-javascript">// ...scores collects everything after the first argument
function printResults(name, ...scores) {
  console.log(`${name}'s scores:`, scores);
}

printResults("User1", 88, 92, 76);
// User1's scores: [88, 92, 76]

printResults("User2", 95);
// User2's scores: [95]

printResults("User3", 70, 85, 90, 88, 77);
// User3's scores: [70, 85, 90, 88, 77]
</code></pre>
<p>The rest parameter always has to be last. You can have as many named parameters before it as you want. But once you write <code>...</code> in the parameter list, nothing else can come after it.</p>
<pre><code class="language-javascript">const [first, second, ...remaining] = [10, 20, 30, 40, 50];
console.log(first);     // 10
console.log(second);    // 20
console.log(remaining); // [30, 40, 50]

// Works with objects too
const { name, ...rest } = { name: "User1", age: 28, city: "Delhi" };
console.log(name); // "User1"
console.log(rest); // { age: 28, city: "Delhi" }
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/5d78a88d-e4ae-4a7e-988c-fb36afcb6914.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Spread vs Rest</strong></h2>
<p>The real question is: how do you tell which one you're looking at? The answer is where the <code>...</code> appears.</p>
<p>If it's on the right side of an assignment, or inside a function call, or inside an array or object literal, it's spread. It's taking something and expanding it. If it's in a function's parameter definition, or on the left side of a destructuring assignment, it's rest. It's collecting things that haven't been named yet.</p>
<table>
<thead>
<tr>
<th>Spread (...)</th>
<th>Rest (...)</th>
</tr>
</thead>
<tbody><tr>
<td>Appears in function <strong>calls</strong>, not definitions</td>
<td>Appears in function <strong>definitions</strong>, not calls</td>
</tr>
<tr>
<td>Appears inside <code>[ ]</code> or <code>{ }</code> literals</td>
<td>Appears on left side of destructuring</td>
</tr>
<tr>
<td>Takes one thing and expands it into many</td>
<td>Takes many things and collects them into one</td>
</tr>
<tr>
<td>Works on arrays, objects, and strings</td>
<td>Result is always a real array</td>
</tr>
</tbody></table>
<h2><strong>Practical Use Cases</strong></h2>
<p><strong>Passing an array as function arguments.</strong> Some functions expect individual arguments, not arrays.</p>
<pre><code class="language-javascript">const scores = [88, 76, 95, 63];

// Math.max doesn't take arrays, it takes individual numbers
Math.max(scores);         // NaN : won't work
Math.max(...scores);       // 95 : works
</code></pre>
<p>**<br />Adding an item to an array without mutating.**</p>
<pre><code class="language-javascript">const cart = ["shoes", "hat"];

// Add an item without touching the original
const newCart = [...cart, "jacket"];
// ["shoes", "hat", "jacket"]

// cart is still ["shoes", "hat"]
</code></pre>
<p><strong>Writing utility functions that accept any number of arguments.</strong> Rest makes this clean without needing the old <code>arguments</code> object.</p>
<pre><code class="language-javascript">function sum(...numbers) {
  return numbers.reduce((total, n) =&gt; total + n, 0);
}

sum(1, 2);              // 3
sum(10, 20, 30);        // 60
sum(5);                // 5
sum();                  // 0
</code></pre>
<p><strong>Stripping one key from an object.</strong> A common pattern when you need to pass an object somewhere but want to exclude a specific field, like removing a password before sending user data to the client.</p>
<pre><code class="language-javascript">// removing a key via destructuring + rest
const userData = {
  id: 1,
  name: "User1",
  password: "secret123",
  role: "admin"
};

// Pull out password, keep everything else
const { password, ...safeData } = userData;
// safeData = { id: 1, name: "User1", role: "admin" }
// password variable holds "secret123" but isn't passed anywhere
</code></pre>
<h2><strong>What You Get Out Of This</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/7c137c35-b061-4c93-b541-be8f40e36541.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">MDN Web Docs : Spread syntax</a></p>
</li>
<li><p><a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">MDN Web Docs : Rest parameters</a></p>
</li>
<li><p><a href="http://javascript.info/rest-parameters-spread">JavaScript.info : Rest parameters and spread syntax.</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Async / Await]]></title><description><![CDATA[JavaScript runs on a single thread. That means while it's waiting for something to finish, like a network request or a file read, it can't do anything else. Early JavaScript handled this with callback]]></description><link>https://blog.saumyagrawal.in/async-await</link><guid isPermaLink="true">https://blog.saumyagrawal.in/async-await</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Tue, 17 Mar 2026 13:15:00 GMT</pubDate><content:encoded><![CDATA[<p>JavaScript runs on a single thread. That means while it's waiting for something to finish, like a network request or a file read, it can't do anything else. Early JavaScript handled this with callbacks. You'd pass a function, and the runtime would call it when the work finished.</p>
<p>That worked, until it didn't. User1 builds a feature: fetch the user, then fetch their orders, then fetch the details for the first order. Each step depends on the previous one. With callbacks, that code looks like a triangle pointing right, indented so deep it falls off the screen. This is known as callback hell.</p>
<p>Promises arrived in ES6 and cleaned things up. Instead of passing callbacks into every function, you got an object that represented a value that would exist sometime in the future. You could chain <code>.then()</code> calls. Errors could propagate through a single <code>.catch()</code>. Much better. But still not quite natural to read, especially once chains got long.</p>
<p>Async/await landed in ES2017. It didn't replace Promises, but it's built directly on top of them. What it changed was how you write code that uses Promises. Instead of chaining, you write code that looks like it runs top to bottom, the way you'd read a recipe. The JavaScript engine handles all the asynchronous mechanics underneath.</p>
<h2><strong>What "Syntactic Sugar" Actually Means Here</strong></h2>
<p>You'll hear async/await described as syntactic sugar over Promises. Syntactic sugar means the compiler translates your code into something else before running it. The sugar is real functionality, just written in a way that's easier for humans to follow.</p>
<p>When you mark a function <code>async</code>, two things happen. One: the function now always returns a Promise, even if you return a plain value. Two: you can use <code>await</code> inside it. That's the whole change at the surface level. Under the hood, the engine converts your await expressions into Promise chains. You write the readable version, the engine runs the Promises.</p>
<pre><code class="language-javascript">// With Promises
function getUser() {
  return fetch('/api/user')
    .then(res =&gt; res.json())
    .then(data =&gt; data.name);
}

// With async/await
async function getUser() {
  const res  = await fetch('/api/user');
  const data = await res.json();
  return data.name;
}
</code></pre>
<p>Same result. The async version reads like synchronous code. That's the entire point.</p>
<h2><strong>How Async Functions Work</strong></h2>
<p>Mark any function with <code>async</code> and it changes one thing about its return behavior: it always wraps the return value in a Promise. If you return a string, the caller gets <code>Promise&lt;string&gt;</code>. If you return nothing, they get <code>Promise&lt;undefined&gt;</code>. If you return a Promise, it stays a Promise.</p>
<pre><code class="language-javascript">async function greet() {
  return "hello";
}

// greet() doesn't return "hello". it returns Promise { "hello" }
greet().then(val =&gt; console.log(val));  // "hello"

// inside another async function:
const msg = await greet();  // msg = "hello"
</code></pre>
<p>The <code>async</code> keyword on its own doesn't do much. The real behavior change comes from <code>await</code> inside it.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/20c93417-465c-4cf5-845d-ea7b8d7c0374.png" alt="" style="display:block;margin:0 auto" />

<p><code>await</code> pauses the function it's in, not the whole program. The JavaScript engine keeps running other things. When the Promise resolves, the function resumes from where it left off.</p>
<h2><strong>The Await Keyword</strong></h2>
<p><code>await</code> only works inside <code>async</code> functions. Put it in front of any expression that returns a Promise, and execution pauses at that line until the Promise settles. If it resolves, you get the value. If it rejects, an error is thrown at that line.</p>
<p>You can await anything that returns a Promise: <code>fetch</code>, database queries, file reads, timeouts wrapped in Promises, third-party APIs. You can also await a non-Promise value, but it just unwraps immediately. Not useful, but not an error either.</p>
<pre><code class="language-javascript">async function loadDashboard(userId) {
  // Each line waits for the previous one to finish
  const user   = await fetchUser(userId);
  const orders = await fetchOrders(user.id);
  const prefs  = await fetchPreferences(user.id);

  return { user, orders, prefs };
}

// Compare this to the callback version:
fetchUser(userId, function(user) {
  fetchOrders(user.id, function(orders) {
    fetchPreferences(user.id, function(prefs) {
      // you get the idea
    })
  })
})
</code></pre>
<h2><strong>Error Handling</strong></h2>
<p>If an awaited Promise rejects and you don't catch it, the error bubbles up and becomes an unhandled rejection. In Node.js, that can crash your process. In the browser it shows up in the console, and depending on your setup, it might get swallowed silently.</p>
<p>The standard way to handle errors in async functions is <code>try/catch</code>. Wrap the await calls that might fail, and the catch block gets control when anything throws.</p>
<pre><code class="language-javascript">// error handling with try-catch
async function loadProfile(userId) { 
    try { 
        const res = await fetch(/api/users/${userId});

        // fetch() doesn't reject on 404. manual checks
        if (!res.ok) throw new Error(`HTTP error: ${res.status}`);

        const data = await res.json();
        return data;
      } catch (err) { 
        // One catch handles network failures AND the throw above 
            console.error("Failed to load profile:", err.message); 
            return null; 
        } 
}
</code></pre>
<p>You can also catch errors at the call site instead of inside the function, using <code>.catch()</code> on the returned Promise. Both work. The try/catch version is usually cleaner when you need to handle multiple possible failure points inside one function.</p>
<h2><strong>Promises vs Async/Await</strong></h2>
<p>These aren't competing approaches. Async/await is Promises. If you have a function that returns a Promise, you can either <code>.then()</code> it or <code>await</code> it. The choice is about readability, not capability.</p>
<p>There are a few cases where Promises with their methods are actually more expressive. Running multiple things in parallel is the clearest example.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/89e046aa-11a5-42bc-b2af-c56e8ac50a7c.png" alt="" style="display:block;margin:0 auto" />

<h4><strong>Promise chains</strong></h4>
<ul>
<li><p><code>Promise.all()</code> run things in parallel</p>
</li>
<li><p><code>Promise.race()</code> first one wins</p>
</li>
<li><p><code>Promise.allSettled()</code> wait for all, keep errors</p>
</li>
<li><p>Chaining can get harder to read as it grows</p>
</li>
</ul>
<h4><strong>Async/await</strong></h4>
<ul>
<li><p>Reads like synchronous code top-to-bottom</p>
</li>
<li><p>Try/catch for error handling</p>
</li>
<li><p>Easier to step through in a debugger</p>
</li>
</ul>
<pre><code class="language-javascript">// Sequential: 3 seconds total (each waits for the last)
const user     = await fetchUser(id);
const orders   = await fetchOrders(id);
const wishlist = await fetchWishlist(id);

// Parallel: ~1 second total (all three start at the same time)
const [user, orders, wishlist] = await Promise.all([
  fetchUser(id),
  fetchOrders(id),
  fetchWishlist(id),
]);
</code></pre>
<h2><strong>What You Get Out Of This</strong></h2>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0f68b460-7cf2-44d2-8c61-e68cb3868a1d.png" alt="" style="display:block;margin:0 auto" />

<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">MDN Web Docs : async function</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await">MDN Web Docs : await</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises">MDN Web Docs : Using Promises</a></p>
</li>
<li><p><a href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/">Jake Archibald Blog</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[From Variables to Objects: Understanding OOP in JavaScript]]></title><description><![CDATA[When you first start writing code, everything feels manageable. You have a few variables, maybe a function or two, and the whole thing fits on one screen. You can read it top to bottom and understand ]]></description><link>https://blog.saumyagrawal.in/from-variables-to-objects-understanding-oop-in-javascript</link><guid isPermaLink="true">https://blog.saumyagrawal.in/from-variables-to-objects-understanding-oop-in-javascript</guid><category><![CDATA[oop]]></category><category><![CDATA[OOPS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Fri, 13 Mar 2026 08:36:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/4686ceaf-a774-49eb-addc-59372175189d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you first start writing code, everything feels manageable. You have a few variables, maybe a function or two, and the whole thing fits on one screen. You can read it top to bottom and understand exactly what is going on. That feeling is great, and it lasts for a while.</p>
<p>Then your program grows. Say you are building something for college or work, and you need to track a group of candidates. You write something like this:</p>
<pre><code class="language-javascript">let student1Name  = "Chintu";
let student1Age   = 19;
let student1Grade = "A";

let student2Name  = "Pintu";
let student2Age   = 21;
let student2Grade = "B";

let student3Name  = "Mintu";
let student3Age   = 20;
let student3Grade = "A";


// Enter 50 more candidates
</code></pre>
<p>This works till the list starts to increase, and writing <code>console.log</code> for every candidate becomes a painful process. Adding new information becomes draining, and your code becomes more prone to typos. This is not something that is only related to new programmers. The code you are writing is functioning, but it does not scale. It is also fragile in ways that are not visible until something goes wrong.</p>
<p>There are a few principles that good programmers use to avoid situations like this, and they each have a name:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/34889e60-4d65-4355-a5f2-0859340f62ac.png" alt="" style="display:block;margin:0 auto" />

<p><strong>Object-Oriented Programming</strong> brings these principles together. You define the candidates using a template to define all their properties. This helps to create as many students as needed, tracking all the changes made. This template is known as a <strong>class.</strong></p>
<h2><strong>What Does "Object-Oriented" Actually Mean?</strong></h2>
<p>Object-Oriented Programming is a style of writing code where you group related data and behaviour together into something called an <strong>object</strong>. A collection of properties is combined under one variable name, carrying methods along with it.</p>
<p>Consider a hospital that manages patients. The information of a patient, such as their name, age, and diagnosis are not kept in separate rooms. A single patient record is kept in one place. A doctor looks at the record, updates it, and reads from it. The data and the actions on that data live together. That is exactly what OOP is trying to replicate in code.</p>
<h3>Real Life Analogy: Phone</h3>
<p>Apple did not just create a single iPhone 17; they created a model defining the iPhone 15 as a device with an exact display size, camera, battery, call feature, and a camera. This specification is not an actual phone; rather, it is a description of what the phone will be.<br />Using this single specification, the factory produces millions of actual iPhones. The iPhone 17 owned by you and your friend are completely different physical objects. You may have an iPhone 17 that has 128GB of memory, and your friend may own an iPhone 17 your friend has 256GB of memory. You have two different iPhones. However, your iPhone and your friend's iPhone are both produced using the same model definition. Consequently, the way your iPhone and your friend's iPhone function is the same.<br />In JavaScript, the class corresponds to the model definition of the phone. The individual phones manufactured from that class model definition correspond to the objects. You only define the class once, and you create objects that correspond to that class as needed. Each object is unique, but all objects will share the same structure and behaviour as per the definition of the class.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/010502fd-6001-4b8c-93fc-740061bcd73b.png" alt="" style="display:block;margin:0 auto" />

<h2>Writing A Class</h2>
<p>The earlier problem can be solved by using a class describing the properties, which allows you to generate many users or objects from one.<br /><strong>SYNTAX:</strong></p>
<pre><code class="language-javascript">class ClassName {
  // code goes here
}
</code></pre>
<p>This is how class is declared, where <code>class</code> is a keyword followed by the name of the class that starts with a capital letter, which creates a visual difference between a regular variable and a class.</p>
<h3>The Constructor</h3>
<p>Whenever a new class is created, JavaScript invokes a method called the <strong>constructor</strong>. Let's consider an example of a student filling out an enrollment form that would collect information and store it in an object.</p>
<pre><code class="language-javascript">class Student {
  constructor(name, age, grade) {
    this.name  = name;
    this.age   = age;
    this.grade = grade;
  }
}

// Creating student objects from the class
const ram = new Student("Ram", 19, "A");
const shayam = new Student("Shyam", 21, "B");

console.log(ram.name);  // "Ram"
console.log(shayam.age);   // 21
</code></pre>
<p>When you write <code>new Student("Ram", 19, "A")</code>, JavaScript creates a new empty object and then runs a constructor to store the value. Inside the constructor, <code>this</code> refers to a brand new object. Hence, <code>this.name = name</code> indicates to take whatever is passed in as <code>name</code> and attach it to this new object as a property.</p>
<div>
<div>💡</div>
<div>What is <code>this</code>? The keyword <code>this</code> inside a class always refers to the specific object that was just created. When <code>ram</code> is created, <code>this</code> is <code>ram</code>. When <code>shayam</code> is created, <code>this</code> is <code>shayam</code>. Each object is its own separate thing with its own data attached.</div>
</div>

<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/5d88822d-06d9-4df5-91de-859d5c279c99.png" alt="" style="display:block;margin:0 auto" />

<h3>Adding Behaviour With Methods</h3>
<p>Properties store data about an object, whereas methods define what an object can do. A <code>Student</code> object might hold a name and age, but it can also introduce itself, display its grade, or check whether it passed a course.<br />Methods are just functions, but they live inside the class and have access to the object's own data via <code>this</code>.</p>
<pre><code class="language-javascript">class Student {
  constructor(name, age, grade) {
    this.name  = name;
    this.age   = age;
    this.grade = grade;
  }

  // Method: introduce the student
  introduce() {
    return `Hi, my name is \({this.name} and I am \){this.age} years old.`;
  }

  // Method: show grade with a status
  getStatus() {
    if (this.grade === "A" || this.grade === "B") {
      return `\({this.name} is passing with a \){this.grade}.`;
    }
    return `${this.name} needs extra support.`;
  }
}

const karan = new Student("Karan", 18, "A");
const arjun = new Student("Arjun", 20, "C");

console.log(karan.introduce());
console.log(karan.getStatus());
console.log(arjun.introduce());
console.log(arjun.getStatus());
</code></pre>
<p>Notice that <code>karan.introduce()</code> and <code>arjun.introduce()</code> are both calling the same method, but each one knows its own name and age because <code>this</code> points to the right object each time.</p>
<hr />
<h2><strong>Encapsulation</strong></h2>
<p>Encapsulation means the object's data and the code that operates on that data should be kept inside one block, and should not be accessed from outside to mess with internal values.</p>
<p>Here is a concrete example. Imagine a student's grade gets set to something nonsensical, like <code>"Z"</code> , because some part of your code sets it directly without any checks. Encapsulation is about protecting against that.</p>
<pre><code class="language-javascript">class Student {
  constructor(name, age, grade) {
    this.name  = name;
    this.age   = age;
    this.grade = grade;
  }

  // Instead of changing grade directly, use a method
  updateGrade(newGrade) {
    const validGrades = ["A", "B", "C", "D", "F"];

    if (validGrades.includes(newGrade)) {
      this.grade = newGrade;
      console.log(`\({this.name}'s grade updated to \){newGrade}.`);
    } else {
      console.log(`"${newGrade}" is not a valid grade.`);
    }
  }

  introduce() {
    return `Hi, I'm \({this.name}, currently at grade \){this.grade}.`;
  }
}

const rahul = new Student("Rahul", 18, "B");

rahul.updateGrade("A");    //Rahul's grade updated to A.
// This will be rejected
rahul.updateGrade("Z");  // "Z" is not a valid grade.

console.log(rahul.introduce()); // Hi, I'm Rahul, currently at grade A.
</code></pre>
<hr />
<p>Object-Oriented Programming is not about memorising syntax. It's about bringing the disconnected variables and functions under one object. The way class works as a blueprint, a constructor sets up the object, and methods provide behaviour.</p>
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">MDN : Classes</a></p>
</li>
<li><p><a href="http://JavaScript.info">javaScript.info</a><a href="https://javascript.info/classes">: Classes</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">MDN : this</a></p>
</li>
<li><p><a href="http://JavaScript.info">javaScript.info</a><a href="https://javascript.info/object-oriented-programming">: OOP Fundamentals</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering the Context: A Guide to this, call, apply, and bind]]></title><description><![CDATA[JavaScript was first designed to work with objects to group related data together. The problem arrived when functions were written to make work with the object.Consider building an app that greets the]]></description><link>https://blog.saumyagrawal.in/mastering-the-context-a-guide-to-this-call-apply-and-bind</link><guid isPermaLink="true">https://blog.saumyagrawal.in/mastering-the-context-a-guide-to-this-call-apply-and-bind</guid><category><![CDATA[this keyword]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Thu, 12 Mar 2026 19:24:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/7782d290-8989-4e1a-979a-79970304c4c7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript was first designed to work with objects to group related data together. The problem arrived when functions were written to make work with the object.<br />Consider building an app that greets the user whenever they open the app, and it should work with every user. To implement functions, either it should be duplicated inside every object. which means maintaing multiple copies, or object should be passed as an argument every time the function is called, making this a exhausting process.<br />Neither option keeps the code clean. To solve this problem <code>this</code> keyword was introduced. It defined who the current owner is and attach the context whoever is calling the function. <code>this</code> gets set at the time a function is called, not when its written, and may result in losing the value on context when a function is passed around.<br />That is where <code>call()</code>, <code>apply()</code>, and <code>bind()</code> come in. They were added to the language specifically to give developers control over <code>this</code>.</p>
<hr />
<h2>What is <code>this</code> ?</h2>
<p><code>this</code> keyword provides a way to know who called them, and the method and values they contain. When a function is called, <code>this</code> to point to the object that made the call.<br />Example:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/ea64fa93-87c8-4307-97e0-fc51060d18f2.png" alt="" style="display:block;margin:0 auto" />

<h3><code>this</code> in Regular Functions</h3>
<p>When you write a plain function and call it on its own, without any object in front of it, <code>this</code> gets set to the global object (<code>global</code> in Node, <code>window</code> in browser). In strict mode, it becomes <code>undefined</code>.</p>
<pre><code class="language-javascript">function whoAmI() {
  console.log(this);
}

whoAmI(); // window (browser), global (Node) or undefined (strict mode)
</code></pre>
<p>The function is called without any object in front, so this points to the global object and nothing meaningful.</p>
<h3><code>this</code> Inside Objects</h3>
<p>When a function is defined inside an object and called through that object, <code>this</code> refers to the object itself.</p>
<pre><code class="language-javascript">const user = {
  name: "User",
  greet: function() {
    console.log("Hi, I'm " + this.name);
  }
};

user.greet(); // "Hi, I'm User"
</code></pre>
<p>Because <code>user.greet()</code> is called with <code>user</code> as the owner, <code>this</code> points to <code>user</code>, and <code>this.name</code> resolves to <code>"User"</code>. Change the caller, and <code>this</code> changes with it.</p>
<h3>Why It Breaks When You Copy A Method</h3>
<p>Then a method is copied outside the object, stored in a variable, and it is called. <code>this</code> loses the context.</p>
<pre><code class="language-javascript">const user = {
  name: "User",
  greet: function() {
    console.log("Hi, I'm " + this.name);
  }
};

const detached = user.greet;
detached(); // "Hi, I'm undefined"
</code></pre>
<p>You copied the function reference, but <code>this</code> did not come along. When <code>detached()</code> runs, there is no object in front of it, so <code>this</code> is either <code>global</code> or <code>undefined</code>, and <code>this.name</code> comes back as <code>undefined</code>. The same problem happens when you pass an object method into <code>setTimeout</code> or an event listener.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/db95421e-c352-4d7b-b758-fa795ce477aa.png" alt="" style="display:block;margin:0 auto" />

<p>This problem is solved by <code>call()</code>, <code>apply()</code>, and <code>bind()</code>.</p>
<hr />
<h2><code>call()</code>: Borrow a Function</h2>
<p><code>call()</code> <em>invokes a function immediately</em> and allows setting the context for that invocation by adding another argument.</p>
<pre><code class="language-javascript">// SYNTAX
call(thisArg)
call(thisArg, arg1, arg2,...,argN)

// Example
const user = {
  name: "User",
  greet: function() {
    console.log("Hi, I'm " + this.name);
  }
};

const anotherUser = { name: "Tom" };

// detached() broke because this was lost.
// call() fixes it by telling greet exactly what this should be.
user.greet.call(anotherUser);
// "Hi, I'm Tom"

// You can call it for any object you want
user.greet.call({ name: "Bob" });
// "Hi, I'm Bob"
</code></pre>
<p>Taking the same <code>user</code> object from above, we can borrow its <code>greet</code> method and run it for a completely different object.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/1f3f8f8f-f873-45d3-a4a4-f42c68298af8.png" alt="" style="display:block;margin:0 auto" />

<h2><code>apply()</code>: <code>call()</code> With Array Arguments</h2>
<p><code>apply()</code> performs exactly like <code>call()</code>, the only difference is that we can pass multiple arguments in the form of an array instead of passing them one by one. The array gets unpacked into the function's parameter.<br />Take a function that greets a user with a custom message and a language tag. You want to run the same function for two different users, and the arguments you want to pass are already sitting in an array:</p>
<pre><code class="language-javascript">// SYNTAX
apply(thisArg)
apply(thisArg, argsArray)

// example
function greet(message, language) {
  console.log(message + ", " + this.name + " [" + language + "]");
}

const user1 = { name: "user1" };
const user2 = { name: "user2" };

const args = ["Hello", "EN"];

// call: you pass the args one by one
greet.call(user1, "Hello", "EN");  // "Hello, user1 [EN]"

// apply: you pass the args as an array, same result
greet.apply(user1, args);           // "Hello, user1 [EN]"
greet.apply(user2, args);           // "Hello, user2 [EN]"
</code></pre>
<p>The <code>args</code> is an array which could have been received from API response, form input, or another function output.</p>
<div>
<div>💡</div>
<div>Now, the spread operator does the same: <code>greet.call(user1, ...args)</code>. This can replace <code>apply()</code>.</div>
</div>

<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/2ee80e5e-fe17-48ea-8955-2c14b4f44382.png" alt="" style="display:block;margin:0 auto" />

<h2><code>bind()</code>: Lock The Context For Later</h2>
<p>Unlike <code>call()</code> and <code>apply()</code>, <code>bind()</code> does not run the function at all. It creates and returns a brand new function with <code>this</code> permanently locked in, along with the arguments you passed, and this function can be called when needed.</p>
<p><code>bind()</code> can be understood using:</p>
<pre><code class="language-javascript">const user = {
  name: "User",
  greet: function() {
    console.log("Hi, I'm " + this.name);
  }
};

// The bug: this is lost when greet is detached
const detached = user.greet;
detached(); // "Hi, I'm undefined"

// The fix: bind locks this to user permanently
const fixed = user.greet.bind(user);
fixed(); // "Hi, I'm User"

// Same fix for setTimeout — passes the function, not the result
setTimeout(user.greet, 1000);             // "Hi, I'm undefined"
setTimeout(user.greet.bind(user), 1000); // "Hi, I'm User"
</code></pre>
<p>Do not use <code>setTimeout(user.greet(), 1000)</code> with the parentheses included. That calls <code>greet</code> immediately and hands its return value, which is <code>undefined</code>, to <code>setTimeout</code> instead of scheduling the function itself. When passing functions as callbacks, leave the parentheses off, or use <code>bind()</code>.</p>
<p>Another example is:</p>
<pre><code class="language-javascript">function log(...args) {
  console.log(this, ...args);
}

const boundLog  = log.bind("this value", 1, 2);
const boundLog2 = boundLog.bind("new this value", 3, 4);

boundLog2(5, 6);
// "this value", 1, 2, 3, 4, 5, 6
</code></pre>
<p>Let's understand it step by step:</p>
<p><strong>Step 1: the first bind() -</strong> <code>log.bind("this value", 1, 2)</code> creates <code>boundLog</code>. It locks <code>this</code> to <code>"this value"</code> and fills the first two arguments as <code>1</code> and <code>2</code>. Those arguments will always be passed first, no matter how <code>boundLog</code> is called later.</p>
<p><strong>Step 2: trying to re-bind -</strong> <code>boundLog.bind("new this value", 3, 4)</code> tries to create a new function with a different <code>this</code>. Once <code>this</code> is locked by <code>bind()</code>, it cannot be changed, and the <code>"new this value"</code> gets ignored, because the <code>bind()</code> created a wrapper for <code>boundLog</code>, and when you try to create a new wrapper which try to provide new <code>this</code> gets ignored. Although, the value <code>3</code> and <code>4</code> gets added to the argument list.</p>
<p><strong>Step 3: calling boundLog2(5, 6) -</strong> When <code>boundLog2(5, 6)</code> runs, the arguments arrive in the order they were locked in across all the bind calls, followed by whatever you pass at call time. That is why the output is <code>"this value", 1, 2, 3, 4, 5, 6</code>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/d1bdcc9e-224e-4f19-bf1b-d5c5e5025eee.png" alt="" style="display:block;margin:0 auto" />

<p>This behaviour is known as <strong>partial application</strong>.</p>
<hr />
<h2><code>call()</code> vs <code>apply()</code> vs <code>bind()</code></h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th><code>call()</code></th>
<th><code>apply()</code></th>
<th><code>bind()</code></th>
</tr>
</thead>
<tbody><tr>
<td>Runs immediately</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>Returns</td>
<td>result of the function</td>
<td>result of the function</td>
<td>a new bound function</td>
</tr>
<tr>
<td>How args are passed</td>
<td>one by one: (a, b)</td>
<td>as an array: ([a, b])</td>
<td>one by one, at bind or call time</td>
</tr>
<tr>
<td>Can call again later</td>
<td>no, already ran</td>
<td>no, already ran</td>
<td>yes, stored as a function</td>
</tr>
<tr>
<td>Best used for</td>
<td>borrow and run now</td>
<td>run now with array args</td>
<td>callbacks, event handlers, timers</td>
</tr>
</tbody></table>
<hr />
<p>Logically, <code>this</code> should depend on where the function is written. Instead, it depends on who calls the function at the moment it runs. This information helps to understand the behaviour of <code>this</code> in a better way.</p>
<p>Functionally, both <code>call()</code> and <code>apply()</code> are ways to execute a function using a given this, and the only difference is whether the arguments are provided individually or all as an array. Each method behaves differently from the other; <code>bind()</code> is a completely different concept since it returns a new function with a predefined context to call whenever you desire. This makes <code>bind()</code> the best option for use with callbacks or any other code that is related to the event.</p>
<hr />
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">MDN: The this keyword</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">MDN: Function.prototype.call()</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">MDN: Function.prototype.apply()</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">MDN: Function.prototype.bind()</a></p>
</li>
<li><p><a href="https://javascript.info/call-apply-decorators">javascript.info: Decorators and Forwarding</a></p>
</li>
<li><p><a href="https://javascript.info/bind">javascript.info: Function Binding</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Cutting the Boilerplate with Arrow Functions]]></title><description><![CDATA[You have encountered this piece of code multiple times at different places, in tutorials, GitHub:
const add = (a, b) => a + b;

This looks weird and alien at first, but once you understand this, it be]]></description><link>https://blog.saumyagrawal.in/cutting-the-boilerplate-with-arrow-functions</link><guid isPermaLink="true">https://blog.saumyagrawal.in/cutting-the-boilerplate-with-arrow-functions</guid><category><![CDATA[#arrowfunction]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Thu, 12 Mar 2026 09:04:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/678e9fe2-9c4a-46d4-b0ae-71aba686214a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You have encountered this piece of code multiple times at different places, in tutorials, GitHub:</p>
<pre><code class="language-javascript">const add = (a, b) =&gt; a + b;
</code></pre>
<p>This looks weird and alien at first, but once you understand this, it becomes a default for you to use in code.</p>
<h2>What Are Arrow Functions?</h2>
<p><strong>Arrow functions</strong> are just a shorter way to write functions. That is the whole story. They behave similarly to regular functions in most cases; their syntax requires less typing and looks natural.</p>
<p>This is how a Function looks:</p>
<pre><code class="language-javascript">function greet(name) {
  return "Hello, " + name;
}

console.log(greet("User")); // "Hello, User"
</code></pre>
<p>The same function can be written using arrow functions:</p>
<pre><code class="language-javascript">const greet = (name) =&gt; {
  return "Hello, " + name;
};

console.log(greet("User")); // "Hello, User"
</code></pre>
<p>They produce the same output; the difference lies in the structure of the functions. The <code>function</code> keyword is dropped, and an arrow <code>=&gt;</code> is added between the parameter and the body.</p>
<h3>Basic Syntax Breakdown</h3>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/beb86d29-7dcb-4a53-85bb-0488a8568476.png" alt="" style="display:block;margin-left:auto" />

<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/2f0750df-9c1e-4902-b848-c825d4ed021d.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Arrow Function with Single Parameter</h2>
<p>When arrow functions take a single parameter, the parentheses can be dropped.</p>
<pre><code class="language-javascript">// With parentheses, always valid
const shout = (word) =&gt; {
  return word.toUpperCase();
};

// Without parentheses, also valid with a single parameter
const shout = word =&gt; {
  return word.toUpperCase();
};

console.log(shout("hello")); // "HELLO"
</code></pre>
<div>
<div>💡</div>
<div>It is a good practice to use parentheses in your code to avoid confusion.</div>
</div>

<hr />
<h2>Arrow Function with Multiple Parameters</h2>
<p>When you have two or more parameters, the parentheses are not optional. They are required.</p>
<pre><code class="language-javascript">// Two parameters
const add = (a, b) =&gt; {
  return a + b;
};

console.log(add(3, 5));  // 8

// Three parameters
const fullName = (first, middle, last) =&gt; {
  return first + " " + middle + " " + last;
};

console.log(fullName("Amar", "Akbar", "Anthony")); // "Amar Akbar Anthony"
</code></pre>
<p>When there are no parameters, parentheses are still needed:</p>
<pre><code class="language-javascript">const greetWorld = () =&gt; {
  return "Hello, World!";
};

console.log(greetWorld()); // "Hello, World!"
</code></pre>
<hr />
<h2>Implicit Return vs Explicit Return</h2>
<p>An <strong>explicit return</strong> means you write the <code>return</code> keyword yourself, inside curly braces.</p>
<pre><code class="language-javascript">const square = (n) =&gt; {
  return n * n; // explicit return
};
</code></pre>
<p>An <strong>implicit return</strong> means the curly braces and the <code>return</code> keywords are dropped, and the arrow function will automatically return whatever expression follows the arrow:</p>
<pre><code class="language-javascript">const square = (n) =&gt; n * n; // implicit return

console.log(square(4)); // 16
console.log(square(9)); // 81
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0b316815-44b7-417e-997f-c6b363555a7e.png" alt="" style="display:block;margin:0 auto" />

<p>Here are some examples of the usage of these return types:</p>
<pre><code class="language-javascript">// Implicit

// Multiply two numbers
const multiply = (a, b) =&gt; a * b;
console.log(multiply(6, 7));  // 42

// Check if a number is even
const isEven = (n) =&gt; n % 2 === 0;
console.log(isEven(4));  // true
console.log(isEven(7));  // false

// Build a greeting string
const greet = (name) =&gt; `Hey, ${name}`;
console.log(greet("User"));  // "Hey, User"
</code></pre>
<pre><code class="language-javascript">// explicit

// Multi line body needs curly braces and explicit return
const describe = (n) =&gt; {
  const type = n % 2 === 0 ? "even" : "odd";
  return `\({n} is \){type}`;
};

console.log(describe(7));   // "7 is odd"
console.log(describe(12));  // "12 is even"
</code></pre>
<p>If curly braces are used, but the return keyword is not used, then the function would return <code>undefined</code></p>
<pre><code class="language-javascript">const broken = (n) =&gt; { n * 2 }; // no return
console.log(broken(5)); // undefined
</code></pre>
<hr />
<h2>Arrow Functions vs Normal Functions</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Normal function</th>
<th>Arrow function</th>
</tr>
</thead>
<tbody><tr>
<td>Syntax</td>
<td>function keyword required</td>
<td>uses <code>=&gt;</code>, no function keyword</td>
</tr>
<tr>
<td>Can be named</td>
<td>yes</td>
<td>only through the variable it is stored in</td>
</tr>
<tr>
<td>Hoisting</td>
<td>declarations are hoisted to the top of the scope</td>
<td>not hoisted (must be defined before use)</td>
</tr>
<tr>
<td><code>this</code> keyword</td>
<td>has its own <code>this</code></td>
<td>inherits <code>this</code> from the surrounding scope</td>
</tr>
<tr>
<td><code>arguments</code> object</td>
<td>Has its own <code>arguments</code></td>
<td>No <code>arguments</code> (Use <code>...args</code> instead)</td>
</tr>
<tr>
<td>Use as constructor</td>
<td>Yes, with <code>new</code></td>
<td>No, throws an error</td>
</tr>
<tr>
<td>Best used for</td>
<td>methods, constructors, complex logic</td>
<td>callbacks, array methods, short utilities</td>
</tr>
</tbody></table>
<h3>Hoisting of Arrow Function</h3>
<p>Normal function declarations get hoisted to the top of their scope, which means you can call them before you define them in the file and it still works. Arrow functions stored in variables do not behave that way:</p>
<pre><code class="language-javascript"> // Normal function: this works 
console.log(sayHi()); // "Hi" -- called before definition

function sayHi() {
  return "Hi";
}

// Arrow function: this throws a ReferenceError
console.log(greet()); // ReferenceError: Cannot access before initialization

const greet = () =&gt; "Hi";
</code></pre>
<hr />
<h2>Arrow Function Importance</h2>
<p>The arrow functions finds its real importance in array methods. Array Methods take a function as an argument, and make the code readable when used with arrow functions.</p>
<p>For example, there is an array of product prices and 10% discount is applied to it:</p>
<pre><code class="language-javascript">const prices = [29.99, 49.99, 9.99, 89.99];

// Using a normal function inside map
const discounted = prices.map(function(price) {
  return price * 0.9;
});

// Using arrow function
const discounted = prices.map((price) =&gt; price * 0.9);

console.log(discounted);
// [26.991, 44.991, 8.991, 80.991]
</code></pre>
<p>The arrow function makes things fit in a single line.</p>
<hr />
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">MDN: Arrow function expressions</a></p>
</li>
<li><p><a href="http://javascript.info">javascript.info</a><a href="https://javascript.info/arrow-functions-basics">: Arrow functions, the basics</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[JS Functions Demystified: Declarations vs. Expressions]]></title><description><![CDATA[You are writing a JavaScript code, and want to implement a functionality repeatedly in your code. To do that, you would have to copy paste the code multiple times to make it work. This process would e]]></description><link>https://blog.saumyagrawal.in/js-functions-demystified-declarations-vs-expressions</link><guid isPermaLink="true">https://blog.saumyagrawal.in/js-functions-demystified-declarations-vs-expressions</guid><category><![CDATA[functions]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Thu, 12 Mar 2026 07:44:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a1493b70-5725-41f0-934b-0e2d0644eda4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You are writing a JavaScript code, and want to implement a functionality repeatedly in your code. To do that, you would have to copy paste the code multiple times to make it work. This process would eventually become taxing, and it would violate the <strong>DRY</strong> principle, Don't Repeat Yourself ! Functions are the solution to this problem.<br />Functions are named container for a logic that can be written in two ways. Lets demistify the ways the functions can be declared and how it can be used.</p>
<h2>What is a Function?</h2>
<p>Functions can be compared to a recipe card in a kitchen. It doesn't do anything unless someone picks it up, follows the instructions on the card, and creates the actual dish. In writing code, you are writing the recipe card by writing a function. Calling a function is the same as cooking from a recipe.Let's understand this through a simple example to greet user whenever a user enters a website:</p>
<pre><code class="language-javascript">// Doing this manually for every user is painful
console.log("Hello, User1");
console.log("Hello, User2");
console.log("Hello, User3");
</code></pre>
<p>This will be a painful process when the number of user keeps on increasing. Hence, we use functions:</p>
<pre><code class="language-javascript">function greet(name) {
  console.log(`Hello, ${name}`);
}

greet("User1");
greet("User2");
greet("User3");

// Output
// Hello User1
// Hello User2
// Hello User3
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/56563be3-7074-45d5-a64f-5794e70153ab.png" alt="" style="display:block;margin:0 auto" />

<p>The parameter gets filled with the argument whenever the function is called.</p>
<p>Functions can also give back a value using the <code>return</code> keyword which can be stored and used it elsewhere:</p>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}

const total = add(5, 3);
console.log(total); // 8
</code></pre>
<p>When the <code>return</code> is encountered, the execution stops and send the value. If a value is returned, the line of code written after the return statement will not be executed.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/9600fd54-1eca-4326-be46-3f8c0b6835e0.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>Function Declaration Syntax</strong></h2>
<p>The function declaration starts with a keyword <code>function</code>, followed by a function name, along with parameters enclosed in parentheses if the function returns.</p>
<pre><code class="language-javascript">function multiply(a, b) {
  return a * b;
}

console.log(multiply(4, 6));   // 24
console.log(multiply(10, 3));  // 30
</code></pre>
<p>The function <code>multiply</code> is the block of code that can be called repeatedly and each function call is independent.</p>
<div>
<div>💡</div>
<div>Function names in JavaScript use <strong>camelCase</strong> by convention.</div>
</div>

<p>Another practical example can be:</p>
<pre><code class="language-javascript">function addTax(price, taxRate) {
  const tax = price * (taxRate / 100);
  return price + tax;
}

console.log(addTax(100, 18));   // price: 100, tax: 18%
console.log(addTax(250, 8));    // price: 250, tax: 8%
Function Expression Syntax
</code></pre>
<h2><strong>Function Expression Syntax</strong></h2>
<p>Function Expression is another way to create functions where a function is assigned to a variable. There is no function name as the variable name suffices.</p>
<pre><code class="language-javascript">const multiply = function(a, b) {
  return a * b;
};

console.log(multiply(4, 6));   // 24
console.log(multiply(10, 3));  // 30
</code></pre>
<p>The output is identical which means both fucntion works the same. The difference lies in how JavaScript handles the function.</p>
<h2>Declaration vs Expression</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Declaration</th>
<th>Expression</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Syntax starts with</strong></td>
<td><code>function name() {}</code></td>
<td><code>const name = function() {}</code></td>
</tr>
<tr>
<td><strong>Can be called before it appears in file</strong></td>
<td>Yes (hoisted)</td>
<td>No (not hoisted)</td>
</tr>
<tr>
<td><strong>Stored in a variable</strong></td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td><strong>Can be passed as an argument to another function</strong></td>
<td>Technically yes, but uncommon</td>
<td>Yes, very common</td>
</tr>
<tr>
<td><strong>Can be anonymous (no name)</strong></td>
<td>No, name is required</td>
<td>Yes</td>
</tr>
<tr>
<td><strong>Common use case</strong></td>
<td>Utility functions, top-level logic</td>
<td>Callbacks, conditionally defined logic</td>
</tr>
</tbody></table>
<h2><strong>Hoisting</strong></h2>
<p>When you execute a code, JavaScript doesn't run it line by line on the first read. Instead it scans the entire code on the first read to find all function declaration and variables and register them. This is called <strong>hoisting</strong>, where the declarations are placed at the top of the scope before the code runs. This means you can call a function declaration even if the call appears above the function definition in your file:</p>
<pre><code class="language-javascript">// Calling the function BEFORE it is defined in the file
console.log(square(5));  // This works fine

function square(n) {
  return n * n;    // 25
}
</code></pre>
<p>Function expression on the other hand, does not get hoisted. The variable is hoisted instead, but not the function. When the JavaScript runs the code line by line, and finally encounters the function to assign to that hoisted variable, the variable remains <code>undefined</code> or throws an error if declared with <code>const</code> or <code>let</code>.</p>
<pre><code class="language-javascript">// Calling before the expression is defined
console.log(square(5));  // ReferenceError: Cannot access 'square' before initialization

const square = function(n) {
  return n * n;
};
</code></pre>
<p>JavaScript know that <code>square</code> exist, but the function is not yet assigned to it. The variable lives in the <strong>temporal dead zone</strong> until the function is assigned to it in the case of <code>const</code> and <code>let</code>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0eec3e7f-e6fd-4518-8866-e34cea1a4033.png" alt="" style="display:block;margin:0 auto" />

<h2><strong>When to Use Each One</strong></h2>
<p>Both function definition works, the use case depends on the readability and intent.</p>
<p><strong>Use Function declaration when:</strong> a named reuable utility is required that will not be reassigned which should be available across the file.</p>
<pre><code class="language-javascript">// A reusable utility - declaration makes sense here
function formatCurrency(amount) {
  return "$" + amount.toFixed(2);
}

console.log(formatCurrency(9.5));   // $9.50
console.log(formatCurrency(100));   // $100.00
</code></pre>
<p><strong>Use a function expression when:</strong> a function is passed to another function, assign different fucntions in different conditions, or treating the fucntion as data. Callbacks, event handlers, and configuration options are all common situations where expressions feel natural.</p>
<pre><code class="language-javascript">const numbers = [3, 1, 8, 2, 5];

// Passing a function expression directly as an argument
const sorted = numbers.sort(function(a, b) {
  return a - b;
});

console.log(sorted);    // [1, 2, 3, 5, 8]
</code></pre>
<p>Another case:</p>
<pre><code class="language-javascript">const isLoggedIn = true;

const getWelcome = isLoggedIn
  ? function() { return "Welcome back!"; }
  : function() { return "Please log in."; };

console.log(getWelcome()); // Welcome back!
</code></pre>
<h2><strong>Function Scope</strong></h2>
<p>Function is JavaScript creates private space for variables declared with <code>const</code> or <code>let</code> inside the functions. Code outside the function will not be able to access the variable declared inside the function. This is known as <strong>local scope</strong>.</p>
<pre><code class="language-javascript">function makeGreeting() {
  // local variable
  const message = "Hello from inside!";  // Hello from inside!
  console.log(message);
}

makeGreeting();
// trying to access from outside
console.log(message);  // ReferenceError: message is not defined
</code></pre>
<p>The function did not encounter an error, but the moment an attempt was made to access the variable from outside of the function, the variable does not exist in the outer space.</p>
<p>Although, a function can access variables that are declared outside. They are known as <strong>global variables</strong>. The function looks for the variable outside if it cannot find variable in the outer scope.</p>
<pre><code class="language-javascript">const siteName = "MyShop";  // defined in outer scope

function showBanner() {
  // siteName is not declared here, so JS looks outward
  console.log("Welcome to " + siteName);
}

showBanner();  // Welcome to MyShop
</code></pre>
<p>The visual model is:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b230893f-2666-433a-9e72-4d9c9810103b.png" alt="" style="display:block;margin:0 auto" />

<p>This scoping behaviour makes the function stay independent. Two functions can use variables with the same name inside its own scope without throwing an error.</p>
<hr />
<p>Almost all of the JavaScript code that you will create will have functions at its core. In addition to knowing what a function is, how to create one using the two primary syntaxes, how to distinguish between a function declaration and function expression based on hoisting, and the scope, return values, default parameters, and passing functions as parameters.</p>
<p>To summarize the above: function declarations get hoisted while function expressions do not. Functions create their unique scope. Use return to get back a value whenever you need to return a value from a function, and since functions in JavaScript are also values, you can pass them around as if they were any other data type; this is what provides so much power and flexibility to JavaScript as a programming language.</p>
<hr />
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function">MDN: function declaration</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function">MDN: function expression</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting">MDN: Hoisting</a></p>
</li>
<li><p><a href="http://JavaScript.info">JavaScript.info</a><a href="https://javascript.info/function-basics">: Function basics</a></p>
</li>
<li><p><a href="http://JavaScript.info">JavaScript.info</a><a href="https://javascript.info/function-expressions">: Function expressions</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Under the Hood:
How Node.js Actually Runs Your Code]]></title><description><![CDATA[There is a whole world that exists between your JavaScript code and the machine that executes it. When you first started using Node.js, you heard terms like non-blocking code and event loop. We accept]]></description><link>https://blog.saumyagrawal.in/under-the-hood-how-node-js-actually-runs-your-code</link><guid isPermaLink="true">https://blog.saumyagrawal.in/under-the-hood-how-node-js-actually-runs-your-code</guid><category><![CDATA[v8 engine]]></category><category><![CDATA[libuv]]></category><category><![CDATA[Event Loop]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Wed, 11 Mar 2026 10:57:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/d09483ef-4cf6-4f4b-807b-b1c0194b6ccd.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There is a whole world that exists between your JavaScript code and the machine that executes it. When you first started using Node.js, you heard terms like <strong>non-blocking code</strong> and <strong>event loop</strong>. We accepted these terms without digging deeper until the code you wrote behaved differently from your expectations, whether the process was slow or the sequence of operations was different. The explanation for these behaviors lies in two pieces of software: <strong>V8</strong> and <strong>libuv</strong>.</p>
<p>Node.js is, in reality, a collection of different software components where V8 and libuv are primary to operations:</p>
<ul>
<li><p><strong>V8 Engine:</strong> This is the core engine that parses and executes your JavaScript, transforming it into machine code that the processor can understand.</p>
</li>
<li><p><strong>libuv:</strong> This C++ library is responsible for handling the file system, networking, timers, and the event loop, enabling Node to perform asynchronous, non-blocking tasks.</p>
</li>
</ul>
<h2><strong>V8: The JavaScript Engine</strong></h2>
<p>The JavaScript engine was built by Google for Chrome. It is responsible for the execution of JavaScript code and executes it as fast as possible. When Ryan Dahl created Node.js, it was embedded with V8 to make JavaScript run outside the browser.<br />The journey of the code in a V8 engine would roughly look like this:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a6780bb6-18a2-42c5-8058-81cad904055c.png" alt="" style="display:block;margin:0 auto" />

<h3>The Parser</h3>
<p>The first job of V8 is to parse the code, that is, it would read through the code and build an <strong>Abstract Syntax Tree (AST)</strong>. AST is a structured representation of the code. Consider a line of code: <code>const x = 5 + 3</code> where it forms a tree of nodes of variable declaration, containing a binary expression, containing two number literals.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b33ca181-6d85-474c-b1d3-488ab8eb0fac.png" alt="" style="display:block;margin:0 auto" />

<p>Parser's job is to throw <code>SyntaxError</code> even before the code is run. It looks for basic mistakes in your line of code.</p>
<pre><code class="language-javascript">const x = ;        // expected expected;
function ()  {}    // identifier expected
const return = 5;  // 'return' is not allowed as a variable declaration name.
</code></pre>
<p><strong>How to see AST on your machine</strong></p>
<p>You can see AST through <strong>Esprima,</strong> which you can install via <code>npm install esprima</code></p>
<pre><code class="language-javascript">// create a js file ast.js
const esprima = require("esprima");

const code = `const x = 5 + 3`;

const ast = esprima.parseScript(code);

console.log(JSON.stringify(ast, null, 2));

// run node ast.js
</code></pre>
<pre><code class="language-javascript">// AST tree
{
  "type": "Program",
  "body": [
    {
      "type": "VariableDeclaration",
      "declarations": [
        {
          "type": "VariableDeclarator",
          "id": {
            "type": "Identifier",
            "name": "x"
          },
          "init": {
            "type": "BinaryExpression",
            "operator": "+",
            "left": {
              "type": "Literal",
              "value": 5,
              "raw": "5"
            },
            "right": {
              "type": "Literal",
              "value": 3,
              "raw": "3"
            }
          }
        }
      ],
      "kind": "const"
    }
  ],
  "sourceType": "script"
}
</code></pre>
<h3><strong>Ignition: The Interpreter</strong></h3>
<p>V8 hands over the AST to a component called <strong>Ignition</strong>, which compiles the AST into <strong>bytecode</strong>. Bytecode is not machine code, but it is instructions that the CPU understands and is executed by Ignition.</p>
<p>To see how it works:</p>
<p>Either create a JS file with code <code>const x = 5 + 3</code> and run a command <code>node --print-bytecode test.js</code> in your terminal, or directly run <code>node --print-bytecode --print-bytecode-filter="" --eval "const x = 5 + 3"</code> .<br />You will notice an overwhelming response in your terminal, but in simple terms, what it does is:</p>
<pre><code class="language-javascript">// this may vary depending on V8 engine
LdaSmi [5]        // Load Small Integer 5 into the accumulator
Star r0           // Store accumulator into register r0

LdaSmi [3]        // Load Small Integer 3 into the accumulator
Star r1           // Store accumulator into register r1

Ldar r0           // Load r0 back into the accumulator
Add r1            // Add r1 to the accumulator  (5 + 3 = 8)

Star r2           // Store result (8) into register r2, this is x
</code></pre>
<p>The pipeline looks like:</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/17b5b153-4b5d-42a2-8877-b63467f06263.png" alt="" style="display:block;margin:0 auto" />

<h3><strong>TurboFan: The Optimising Compiler</strong></h3>
<p>V8 is pretty efficient in running the code. Ignition watches for the part of the code that executes often. A function, when called multiple times in a loop, is called <strong>hot code,</strong> which is sent to the second compiler called <strong>TurboFan.</strong> Its role is to analyse bytecode and compile it down to an optimised machine code. Now the functions that are frequently being called upon will be processed faster.</p>
<p>A simple function which V8 will optimise:</p>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}

// Call it many times. V8 notices this is "hot"
let total = 0;
for (let i = 0; i &lt; 1_000_000; i++) {
  total = add(total, i); // Always numbers
}
console.log(total); 
</code></pre>
<p>V8 also handles <strong>memory management</strong> through a process called <strong>garbage collection</strong>. When you create objects and variables, V8 allocates memory for them. When the code stops looking for the variables, V8 frees the memory space allocated to them. This is a periodic operation that might affect performance in heavy applications.</p>
<hr />
<h2><strong>libuv: The Asynchronous Bridge</strong></h2>
<p>V8 can execute JavaScript code, but is unable to communicate with a file system, make network requests, or set timers without halting the ongoing process. For asynchronous operations, a communication channel needs to be established with the operating system, where a request can take an unpredictable amount of time. But the process cannot stay in an idle state.</p>
<p>The solution to this problem was <strong>libuv.</strong> It is a C library designed for Node.js that can handle the I/O operations without blocking the rest of your program.</p>
<h3>The Thread Pool</h3>
<p>It is common knowledge that Node.js is <strong>single-threaded</strong>, but libuv maintains worker threads in the background. By default, it provides us with four threads, which can be later configured using an environment variable: <code>UV_THREADPOOL_SIZE</code> .</p>
<pre><code class="language-javascript">// Run Node with 8 libuv threads instead of the default 4
UV_THREADPOOL_SIZE=8 node server.js
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/7b9c8c47-290e-49fb-8e33-0080d5e3f77e.png" alt="" style="display:block;margin:0 auto" />

<p>When <code>fs.readFile()</code> is called, JavaScript registers the callback, and the task of reading the file is handed over to the background threads. The thread is responsible for the blocking work, and when the task is completed, the result is put in the queue. The event loop will then pick it up and call the callback. This is how JavaScript became non-blocking.</p>
<pre><code class="language-javascript">const fs = require('fs');

console.log('1. Script starts');

// This goes to libuv's thread pool. It does NOT block here.
fs.readFile('./data.txt', 'utf8', (err, data) =&gt; {
  console.log('3. File read finished (came back from libuv)');
});

// This runs IMMEDIATELY after registering the file read
console.log('2. Still on the main thread - not blocked');

// output
// 1. Script starts 2. Still on the main thread - not blocked 3. File read finished (came back from libuv)
</code></pre>
<p>In the above code, line 2 prints before line 3, even though line 3 is written above it in the callback. The file reading was happening in the background the entire time line 2 was executing. This ordering is the direct result of how libuv works.</p>
<hr />
<h2><strong>The Event Loop</strong></h2>
<p>The event loop is the bridge between V8 and libuv. As the name says, it is a loop that runs continuously to check for a pending task, and if there are any, it completes them.</p>
<p>Every iteration of the loop is called a <strong>tick</strong>. In every tick, the event loop follows an order of operations. libuv's role is to implement and drive the loop and call V8 whenever there is JavaScript code to execute.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/66d650f9-4c12-4636-90a7-1d700c5bf934.png" alt="" style="display:block;margin:0 auto" />

<p>The phase that is mostly put to use is the <strong>Poll Phase</strong>, where the Node waits for its I/O events. If there is nothing ready, it can block here momentarily, waiting for the OS to signal that a file read is completing, or a network packet is arriving. When work arrives from libuv's thread pool, it lands here.</p>
<hr />
<h3><strong>The Full Picture: V8 + libuv</strong></h3>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/7a6e1973-ec25-4f9c-bf59-da91240aa896.png" alt="" style="display:block;margin:0 auto" />

<p>Your JavaScript code sits at the top. The Node.js APIs like <code>fs</code> or <code>http</code> are the interface Node exposes to you. Below that, V8 handles all the JavaScript execution while libuv handles the asynchronous operations involving the OS. Everything eventually reaches the OS at the bottom.</p>
<p>Let us trace exactly what happens when you run this familiar piece of code, step by step.</p>
<pre><code class="language-javascript">const fs = require('fs');

fs.readFile('file.json', 'utf8', function(err, data) {
  if (err) throw err;
  const users = JSON.parse(data);
  console.log(`Found ${users.length} users`);
});

console.log('Server is ready to accept requests');
</code></pre>
<p>The order of operations:</p>
<ol>
<li><p>V8 parses and starts executing your script</p>
</li>
<li><p><code>fs.readFile</code> is called, and Node.js hands this to libuv</p>
</li>
<li><p>libuv assigns the file read to one of its 4 background threads</p>
</li>
<li><p>V8 continues executing. <code>console.log('Server is ready...')</code> runs immediately</p>
</li>
<li><p>The background thread finishes reading <code>file.json</code> from disk</p>
</li>
<li><p>libuv puts your callback into the poll queue</p>
</li>
<li><p>The event loop picks it up in the poll phase</p>
</li>
<li><p>V8 executes your callback with the file contents</p>
</li>
</ol>
<p>Notice that in step 4, the main thread did not halt its operation, waiting for the OS to finish reading the JSON file, showing that the task of waiting is handled by libuv.</p>
<hr />
<h2><strong>Timers and setImmediate</strong></h2>
<p>Timers are also handled by libuv. Whenever a <code>setTimeout</code> function is called, libuv registers it. When the timer runs out, it places the callback in the queue, and this queue will be checked by the event loop on every tick to run the callbacks that are ready to be served.</p>
<p><code>setImmediate</code> is a function specific to Node that schedules a callback for the <strong>Check Phase</strong>. The check phase comes after the Poll phase, which makes the <code>setImmediate</code> run after the I/O operations in the current tick, but before the timers in the next iteration.</p>
<p>Let's understand the execution order through:</p>
<pre><code class="language-javascript">console.log('A - synchronous, runs first');

setTimeout(() =&gt; {
  console.log('D - setTimeout fires in Timers phase');
}, 0);

setImmediate(() =&gt; {
  console.log('E - setImmediate fires in Check phase');
});

Promise.resolve().then(() =&gt; {
  console.log('C - Promise microtask runs before next phase');
});

console.log('B - still synchronous');

// output
// A - synchronous, runs first
// B - still synchronous
// C - Promise microtask runs before next phase
// D - setTimeout fires in Timers phase
// E - setImmediate fires in Check phase
</code></pre>
<p><strong>C</strong> (Promise) runs before D and E (setTimeout and setImmediate), even though it comes after them. This is because Promise use <strong>microtask queue</strong>, which the event loop prioritizes to clean after every phase. Microtasks always get priority over regular callbacks.</p>
<hr />
<h2>V8 and libuv Task on Different Operations</h2>
<table>
<thead>
<tr>
<th>Operation</th>
<th>V8 performs</th>
<th>libuv performs</th>
</tr>
</thead>
<tbody><tr>
<td>const x = 5 + 3</td>
<td>Compiles and executes it</td>
<td>Nothing</td>
</tr>
<tr>
<td>fs.readFile()</td>
<td>Calls the Node binding</td>
<td>Sends to the thread pool, queues the callback on completion</td>
</tr>
<tr>
<td>setTimeout(fn, 500)</td>
<td>Registers callback reference</td>
<td>Tracks the timer, queues callback after 500ms</td>
</tr>
<tr>
<td>http.get(url, cb)</td>
<td>Calls the binding</td>
<td>Uses OS async networking (epoll/kqueue), queues callback</td>
</tr>
<tr>
<td>new Promise(fn)</td>
<td>Manages microtask queue</td>
<td>Nothing (purely JS)</td>
</tr>
<tr>
<td>crypto.pbkdf2()</td>
<td>Calls the binding</td>
<td>Sends CPU-heavy work to the thread pool</td>
</tr>
</tbody></table>
<hr />
<p>Node.js is a combination of two software: V8 and libuv that work together through the event loop. V8 executes the JavaScript code on the main thread, whereas libuv is responsible for the asynchronous task, helping the Node to stay non-blocking.</p>
<p>The event loop is like a conductor, which, on every tick, works through its phases to run the callback ready to be served through V8. It is to be noted that the main thread should not be blocked with heavy synchronous tasks so that the system is able to handle all operations efficiently. Understanding the architecture helps to understand the sequence of operations and ways to handle heavy tasks.</p>
<p><strong>REFERENCES:</strong></p>
<ul>
<li><p><a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick">Node.js Docs: The Event Loop</a></p>
</li>
<li><p><a href="http://libuv.org">libuv.org : Official documentation</a></p>
</li>
<li><p><a href="https://v8.dev/docs">V8 Developer Docs</a></p>
</li>
<li><p><a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ">Philip Roberts: "What the heck is the event loop anyway?" (JSConf EU)</a></p>
</li>
<li><p><a href="https://nodejs.org/api/worker_threads.html">Node.js Worker Threads</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Stop Using 100 Variables: How JavaScript Objects Save Your Sanity]]></title><description><![CDATA[Consider you are building a social media platform for your college. You can store data in individual variables:
const username = "anon.codes";
const followers = 1240;
const bio = "building stuff on th]]></description><link>https://blog.saumyagrawal.in/stop-using-100-variables-how-javascript-objects-save-your-sanity</link><guid isPermaLink="true">https://blog.saumyagrawal.in/stop-using-100-variables-how-javascript-objects-save-your-sanity</guid><category><![CDATA[Objects]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Tue, 10 Mar 2026 14:11:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/514f823d-db3b-40d2-be1b-3a2c4ab4a1f6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Consider you are building a social media platform for your college. You can store data in individual variables:</p>
<pre><code class="language-javascript">const username = "anon.codes";
const followers = 1240;
const bio = "building stuff on the internet";
const isPrivate = false;
</code></pre>
<p>This works for one person. But, what if you have 100 users? That would make 400 variables only for these four field. It would become a nightmare if you want to add <code>profilePicture</code> for the user, that add 100 variables. You could then try array:</p>
<pre><code class="language-javascript">const user = ["anon.codes", 1240, "building stuff on the internet", false];
</code></pre>
<p>But array are ordered list. To get the follower count, you have to remember it was stored at index 1. If you are building this with a teammate and they rearrange the order, every single read breaks silently. <code>user[1]</code> suddenly returns the bio instead of followers, and the app just shows the wrong thing with no error. That is the kind of bug that takes hours to find.</p>
<p>The real problem with both approaches is the same: the data has no labels. You know what the values mean, but the code does not. This is exactly the problem JavaScript objects were built to solve.</p>
<h2><strong>The JavaScript Objects</strong></h2>
<p>An object is a <strong>collection of key-value pairs</strong>. It allows us to bundle related data and behavior into a single, labeled entity. It is like a library, where every book is labeled with its genre, author, and title. You find them by their name.</p>
<p>Every piece of information has a label or <strong>key</strong> and the actual data or <strong>value</strong>. Here is the same user profile from before, written as an object:</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",   // key: username, value: "anon.codes"
  followers: 1240,          // key: followers, value: 1240
  bio: "building stuff on the internet",
  isPrivate: false,

  // Objects can even hold functions, called methods
  follow: function() {
    this.followers++;
    console.log("New follower added");
  }
};
</code></pre>
<p>This improves readability because we now access data like <code>userProfile.username</code> instead of indexing like <code>user[1]</code>. The relationship between the data is also maintained.<br />That last part, the <code>follow</code> function inside the object, is called a <strong>method</strong>. It is a function that belongs to the object. We will not go deep on methods in this post, but it is good to know they exist: objects can hold both data and behavior in the same place.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/a0e0d726-f7b3-4ed7-bc6a-758fb3147453.png" alt="" style="display:block;margin:0 auto" />

<blockquote>
<p>Everything is an Object or behaves like one.</p>
</blockquote>
<h2><strong>Arrays vs Objects</strong></h2>
<p>Since we started with arrays as a comparison, it helps to see them side by side properly. They are not interchangeable. Each has a job.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/98911a12-b4a2-4454-b56a-7b235282c7de.png" alt="" style="display:block;margin:0 auto" />

<p>Arrays are used to store data of same kind, like a list of usernames, notifications, etc. Objects are used to store different, multiple data for single entity, like a user's username, email, followers and following count, bio, profile picture, etc. In real apps: these two are combined in the form of array of user object, where each item is object of one user.</p>
<hr />
<h2>Creating an Object</h2>
<p>An object is created using curly braces with key-value pair inside it known as <strong>object literal</strong>.</p>
<pre><code class="language-javascript">// Syntax
// Constructor
const o1 = new Object();

// Declaring it directly, commonly used
// example
const userProfile = {
  username: "anon.codes",
  followers: 1240,
  bio: "building stuff on the internet",
  isPrivate: false
};
</code></pre>
<p>The key comes first, then a colon, followed by the value. Each pair is separated by a comma. The keys do not need quotes around them as long as they follow standard variable naming rules (no spaces, no hyphens). The values can be any data type: strings, numbers, booleans, arrays, or even other objects.</p>
<div>
<div>💡</div>
<div>Use <code>const</code> for objects in most situations. You can still freely add, update, and remove properties inside the object. <code>const</code> only prevents you from replacing the whole variable with a different object entirely, but the contents of the object can be altered.</div>
</div>

<h2>Accessing Properties</h2>
<p>There are two ways to read data from an object.</p>
<ol>
<li><strong>Dot Notation</strong></li>
</ol>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  isPrivate: false
};

console.log(userProfile.username);   // "anon.codes"
console.log(userProfile.followers);  // 1240
console.log(userProfile.isPrivate);  // false
</code></pre>
<ol>
<li><strong>Bracket Notation:</strong> Bracket notation lets you pass the key as a string. It looks more like an array, but you are using a name instead of a number. The main reason to use it over dot notation is when your key is stored in a variable rather than written directly.</li>
</ol>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240
};

// Works exactly like dot notation
console.log(userProfile["username"]);   // "anon.codes"

// The real use case: the key is in a variable
const field = "followers";
console.log(userProfile[field]);         // 1240
</code></pre>
<p>To gain a better understanding, let's consider an example where you are building a settings page where a user can edit his information. The field being editing gets stored in another variable like <code>selectedVariable</code>. To access the value, <code>userProfile[selectedField]</code> is needed. The dot notation will not work as <code>userProfile.selectedField</code> would look for <code>selectedField</code> as key, and would not find anything.</p>
<pre><code class="language-javascript">const userProfile = { username: "anon.codes", bio: "building stuff on the internet" };
const selectedField = "bio";

console.log(userProfile[selectedField]);   // "building stuff on the internet"
console.log(userProfile.selectedField);    // undefined 
</code></pre>
<div>
<div>💡</div>
<div>Use dot notation by default. Switch to bracket notation when the key comes from a variable, or when the key contains characters that would break dot notation, like a space or a hyphen.</div>
</div>

<h2><strong>Updating Object Properties</strong></h2>
<p>Updating a property is the same syntax as reading it, but with an assignment on the right.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  bio: "building stuff on the internet"
};

// User gained a new follower
userProfile.followers = 1241;

// User updated their bio
userProfile.bio = "Learn in public. building things.";

console.log(userProfile.followers);  // 1241
console.log(userProfile.bio);        // "Learn in public. building things."
</code></pre>
<p><strong>Objects are mutable.</strong> When you update a property, you are changing the original object in memory. This is different from how strings behave, where every change gives you a new string and the original is untouched. With objects, the change happens in place.</p>
<h2>Adding Properties</h2>
<p>It is not necessary to define all the properties while creating the object. Objects let you add new fields after creation. If you assign value to a key that does not exist yet, then JavaScript adds it for you.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240
};

// User added a profile picture and a location
userProfile.profilePicture = "avatar.jpg";
userProfile.location = "Lolpur";

console.log(userProfile);
// { username: "anon.codes", followers: 1240, profilePicture: "avatar.jpg", location: "Lolpur" }
</code></pre>
<h2>Deleting Properties</h2>
<p>Objects allows deletion of properties that are not needed. Use <code>delete</code> keyword to delete a property.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  tempToken: "abc123xyz"  // session token, not for display
};

// Remove the token before sending the profile to the frontend
delete userProfile.tempToken;

console.log(userProfile);
// { username: "anon.codes", followers: 1240 }

console.log(userProfile.tempToken);  // undefined
</code></pre>
<div>
<div>💡</div>
<div>Stripping sensitive fields from an object before sending it to the client is a very common real-world pattern. You fetch a user from a database, they come back with a hashed password and internal tokens attached. You <code>delete</code> those before the response goes out.</div>
</div>

<h2>Checking If a Property Exist</h2>
<p>If there is a need to check is a property exist or not, <code>in</code> operator is used. It returns <code>boolean</code>.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  bio: "building stuff on the internet"
};

console.log("bio" in userProfile);          // true
console.log("profilePicture" in userProfile); // false

// hasOwnProperty() is an older but equivalent approach
console.log(userProfile.hasOwnProperty("followers"));  // true
console.log(userProfile.hasOwnProperty("location"));   // false
</code></pre>
<div>
<div>💡</div>
<div>Sometimes, you might observe <code>obj.key === undefined</code> being used to check the existence of a property. This should be avoided beacuse there can be a case where a property is set aas <code>undefined</code> intentionally. Hence, <code>in</code> keyword is preferred to distinguish between a property that <strong>doesn't exist</strong> and a property that <strong>exists but is set to </strong><code>undefined</code> .</div>
</div>

<h2>Nested Object</h2>
<p>When the value of a property is another object, then it is known as Nested Object.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  settings: {
    darkMode: true,
    language: "en",
    notifications: false
  }
};

// Access the top-level property
console.log(userProfile.username);                  // "anon.codes"

// Access the nested object's properties by chaining dots
console.log(userProfile.settings.darkMode);         // true
console.log(userProfile.settings.language);         // "en"

// Update a nested property the same way
userProfile.settings.notifications = true;
console.log(userProfile.settings.notifications);    // true
</code></pre>
<h2>Looping Through Object Keys</h2>
<p>To look throught the object, use <code>for...in</code> loop:</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  isPrivate: false
};

for (const key in userProfile) {
  console.log(key + ": " + userProfile[key]);
}

//output
// username: anon.codes
// followers: 1240
// isPrivate: false
</code></pre>
<p>Inside the loop, <code>key</code> is a string holding the current property name. To get the value, you use bracket notation: <code>userProfile[key]</code>. You cannot use dot notation here because <code>key</code> is a variable, not the literal name of a property.</p>
<h3><strong>Methods to access object keys and values</strong></h3>
<p>There are three methods that can be used to access key, and values, and they return an array.</p>
<pre><code class="language-javascript">const userProfile = {
  username: "anon.codes",
  followers: 1240,
  isPrivate: false
};

// Get all the keys
console.log(Object.keys(userProfile));
// ["username", "followers", "isPrivate"]

// Get all the values
console.log(Object.values(userProfile));
// ["anon.codes", 1240, false]

// Get both, as [key, value] pairs
console.log(Object.entries(userProfile));
// [["username", "anon.codes"], ["followers", 1240], ["isPrivate", false]]
</code></pre>
<div>
<div>💡</div>
<div><code>for...in</code> is used to print or inspect where readibility is priority. <code>Object.keys()</code> is useful when you only need the field names, like checking how many properties an object has. <code>Object.entries()</code> is used when you need both key and value together and want to use array methods like <code>.map()</code> or <code>.filter()</code> to transform them.</div>
</div>

<hr />
<p>We started with four loose variables for a single user, saw why that falls apart at scale, and saw why an array is not the right tool for the job either. Objects solve both problems where data stays together, every field has a name, and you can read or update anything without knowing positions.</p>
<p>Objects become reality when you see API response, or someone else's code, and realize you can read it.</p>
<p><strong>References:</strong></p>
<ul>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects">MDN: Working with Objects</a></p>
</li>
<li><p><a href="https://javascript.info/object">JavaScript.info: Objects</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in">MDN: for...in statement</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">MDN: Object.keys()</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Beyond window: Understanding global and globalThis in JavaScript]]></title><description><![CDATA[When you wrote your first line of Node.js code, you probably typed console.log("Hello World") and it just worked. No import. No setup. Nobody told you where console came from, and at the time, it did ]]></description><link>https://blog.saumyagrawal.in/beyond-window-understanding-global-and-globalthis-in-javascript</link><guid isPermaLink="true">https://blog.saumyagrawal.in/beyond-window-understanding-global-and-globalthis-in-javascript</guid><category><![CDATA[Global]]></category><category><![CDATA[global-and-globalThis]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Saumya]]></dc:creator><pubDate>Tue, 10 Mar 2026 09:31:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/05fb9a75-8613-4951-9053-8e3f43ce0534.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you wrote your first line of Node.js code, you probably typed <code>console.log("Hello World")</code> and it just worked. No import. No setup. Nobody told you where <code>console</code> came from, and at the time, it did not matter.</p>
<p>But if you have ever stopped to wonder why <code>console</code>, <code>setTimeout</code>, and <code>process</code> are just... there, ready to use before your code does anything, the answer is <code>global</code>. It is the object Node.js quietly builds before your code even starts running, and it holds everything the runtime gives you for free.</p>
<p>Then in 2020, JavaScript introduced <code>globalThis</code>, which sounds like a small thing but solved a problem that had been quietly annoying developers for years.</p>
<hr />
<h2>What is Node.js, Actually?</h2>
<p>JavaScript was built for browsers. Chrome, Firefox, Safari, all of them come with a JavaScript engine and a set of built-in tools like <code>document</code>, <code>window</code>, and <code>fetch</code> that let your code interact with a webpage.</p>
<p>Node.js had a different idea. It took V8, the same engine Chrome uses to run JavaScript, and stripped out everything browser-specific. The result was a JavaScript runtime that could run anywhere: on a server, on your machine, inside a build tool, wherever.</p>
<p>The language is the same. The environment is different. And just like browsers have an object that holds everything your code needs without importing it, Node.js has its own version of that.</p>
<p>In the browser, that object is <code>window</code>.</p>
<p>In Node.js, it is <code>global</code>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/762ca162-6944-4666-8971-ae25ef45d1d6.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2><code>global</code>: The Object That Holds Everything</h2>
<p>When Node.js starts up, it creates the <code>global</code> object and populates it with every built-in tool your code might need. When you type <code>console.log()</code>, Node.js is actually looking up <code>global.console.log()</code> behind the scenes.</p>
<pre><code class="language-js">// What you write:
console.log("I am global");
setTimeout(() =&gt; {}, 1000);

// What Node.js actually does:
global.console.log("I am global");
global.setTimeout(() =&gt; {}, 1000);
</code></pre>
<p>Node.js lets you skip the <code>global.</code> prefix, so it feels like these things exist on their own. But they are just properties on that one shared object.</p>
<pre><code class="language-js">console.log(global.console === console);       // true
console.log(global.setTimeout === setTimeout); // true
</code></pre>
<p>Here is a look at what lives on <code>global</code> by default:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>What you get</th>
</tr>
</thead>
<tbody><tr>
<td>Output</td>
<td><code>console</code></td>
</tr>
<tr>
<td>Timers</td>
<td><code>setTimeout</code>, <code>setInterval</code>, <code>setImmediate</code>, <code>clearTimeout</code>, <code>clearInterval</code></td>
</tr>
<tr>
<td>Module system</td>
<td><code>require</code>, <code>module</code>, <code>exports</code>, <code>__filename</code>, <code>__dirname</code></td>
</tr>
<tr>
<td>Runtime info</td>
<td><code>process</code></td>
</tr>
<tr>
<td>Data structures</td>
<td><code>Buffer</code></td>
</tr>
<tr>
<td>Async primitives</td>
<td><code>Promise</code></td>
</tr>
<tr>
<td>Universal JS</td>
<td><code>Math</code>, <code>JSON</code>, <code>Date</code>, <code>Error</code></td>
</tr>
</tbody></table>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/748db79e-05c1-4319-b8ec-210f284a2a75.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Why <code>this</code> at the Top Level is Not <code>global</code></h2>
<p>Here is something that catches a lot of people off guard. If you open a Node.js file and log <code>this</code> at the top level, you do not get <code>global</code>.</p>
<pre><code class="language-js">console.log(this);           // {}
console.log(this === global); // false
</code></pre>
<p>The reason is that Node.js does not actually run your file directly. Before execution, it wraps your entire file in a function:</p>
<pre><code class="language-js">// Node.js silently does this before running your code:
(function(exports, require, module, __filename, __dirname) {

  // everything you write ends up in here

});
</code></pre>
<p>So your code is never truly at the top level. It is inside a function, and inside that function, <code>this</code> points to <code>module.exports</code>, not <code>global</code>. <code>module.exports</code> starts as an empty object, which is why you see <code>{}</code>.</p>
<pre><code class="language-js">console.log(this);                   // {}
console.log(this === global);        // false
console.log(this === module.exports); // true
</code></pre>
<p>If you call a regular function (not a method, not in strict mode), <code>this</code> inside it does resolve to <code>global</code>:</p>
<pre><code class="language-js">function test() {
  console.log(this === global); // true
}

test();
</code></pre>
<p>Here is the full picture:</p>
<table>
<thead>
<tr>
<th>Where the code runs</th>
<th>What <code>this</code> becomes</th>
</tr>
</thead>
<tbody><tr>
<td>Browser top level</td>
<td><code>window</code></td>
</tr>
<tr>
<td>Node.js top level</td>
<td><code>module.exports</code> (empty <code>{}</code>)</td>
</tr>
<tr>
<td>Regular function call (non-strict)</td>
<td><code>global</code></td>
</tr>
<tr>
<td>Strict mode function</td>
<td><code>undefined</code></td>
</tr>
<tr>
<td>Method call</td>
<td>the object the method belongs to</td>
</tr>
<tr>
<td>Any environment</td>
<td><code>globalThis</code></td>
</tr>
</tbody></table>
<hr />
<h2>The Problem <code>globalThis</code> Was Built to Solve</h2>
<p>For a long time, Node.js developers used <code>global</code> and browser developers used <code>window</code>. That was fine until someone needed to write code that ran in both.</p>
<p>Say you build a utility library for formatting dates or handling errors and publish it on npm. Browser apps use it. Node.js apps use it. The moment you try to reference the global object directly, you are stuck:</p>
<pre><code class="language-js">// Crashes in Node.js
console.log(window.Math);
// ReferenceError: window is not defined

// Crashes in a browser
console.log(global.Math);
// ReferenceError: global is not defined
</code></pre>
<p>Neither name works in both places. So developers wrote workarounds like this:</p>
<pre><code class="language-js">const globalObject =
  typeof window !== "undefined" ? window :
  typeof global !== "undefined" ? global :
  typeof self   !== "undefined" ? self   :
  null;
</code></pre>
<p>It worked, but it was fragile and ugly. Every shared library had its own version of this block.</p>
<p>ES2020 replaced all of that with one thing.</p>
<hr />
<h2><code>globalThis</code>: One Name That Works Everywhere</h2>
<p><code>globalThis</code> is a standard, universal way to access the global object regardless of where the code is running.</p>
<pre><code class="language-js">// In Node.js:
console.log(globalThis === global); // true

// In a browser:
console.log(globalThis === window); // true

// In a Web Worker:
console.log(globalThis === self);   // true
</code></pre>
<p>That messy workaround from above becomes:</p>
<pre><code class="language-js">const globalObject = globalThis;
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/18355593-a702-47d8-95b1-26e81fa7d6ba.png" alt="" style="display:block;margin:0 auto" />

<p><code>globalThis</code> did not replace <code>global</code> in Node.js. <code>global</code> is still valid and still works. The difference is portability:</p>
<table>
<thead>
<tr>
<th>Environment</th>
<th><code>global</code> works</th>
<th><code>globalThis</code> works</th>
</tr>
</thead>
<tbody><tr>
<td>Node.js</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Browser</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Web Workers</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Deno</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody></table>
<p>If you are writing code that will only ever run in Node.js, <code>global</code> is fine. If there is any chance your code ends up in a browser or gets shared as a library, use <code>globalThis</code>.</p>
<pre><code class="language-js">// Both work in Node.js and point to the same object
console.log(global === globalThis);              // true
console.log(global.Math.PI);                     // 3.141592653589793
console.log(globalThis.Math.PI);                 // 3.141592653589793
console.log(globalThis.setTimeout === setTimeout); // true
</code></pre>
<hr />
<h2>Do Not Put Your Own Variables on <code>global</code></h2>
<p>Node.js will let you attach your own values to <code>global</code>. It will not throw an error. But it is a pattern that tends to create problems you only discover months later.</p>
<p>Here is a common beginner mistake. You have a username that needs to be accessible across multiple files, and attaching it to <code>global</code> seems like a clean shortcut:</p>
<pre><code class="language-js">// app.js
global.username = "User";
console.log("App started");

// greet.js
function greet() {
  console.log("Hello, " + username); // no import, just works
}

greet(); // "Hello, User"
</code></pre>
<p>This works right up until you have ten files, three months of code, and a bug where the username is printing wrong. You open <code>greet.js</code> looking for where <code>username</code> comes from, and there is nothing. No import. No declaration. You now have to trace through every file in the project to find where it was set.</p>
<p>Global variables have no trail. They appear from nowhere and make debugging slow and painful, especially when someone new joins the project.</p>
<p>The fix is straightforward:</p>
<pre><code class="language-js">// user.js
const username = "User";
module.exports = username;

// greet.js
const username = require("./user");

function greet() {
  console.log("Hello, " + username);
}

greet(); // "Hello, User"
</code></pre>
<p>Now anyone reading <code>greet.js</code> knows immediately where <code>username</code> comes from. No searching required. As the codebase grows, that clarity pays off every single time.</p>
<hr />
<h2>Conclusion</h2>
<p>JavaScript was built for the browser, and Node.js pulled it out of that environment entirely. With that move came the need for a global object of its own, and that is <code>global</code>. Every built-in you use in Node.js without importing, <code>console</code>, <code>setTimeout</code>, <code>process</code>, <code>Buffer</code>, lives there.</p>
<p>The <code>this</code> behavior at the top level of a file is a side effect of how Node.js wraps your code in a function before running it. Once you know that, the <code>{}</code> output makes sense.</p>
<p><code>globalThis</code> came along in ES2020 to give developers one consistent name for the global object across every JavaScript environment. In Node.js specifically, <code>global</code> and <code>globalThis</code> point to the same place. Which one you use depends on whether your code is staying in Node.js or needs to travel.</p>
<p>Either way, now you know where <code>console.log</code> actually comes from.</p>
<hr />
<h2>References</h2>
<ul>
<li><p><a href="https://nodejs.org/api/globals.html">Node.js: Global Objects</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis">MDN: globalThis</a></p>
</li>
<li><p><a href="https://javascript.info/global-object">javascript.info: Global Object</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>