<?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[Dipan Roy Choudhury]]></title><description><![CDATA[Dipan Roy Choudhury]]></description><link>https://dipan-roy-choudhury.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 18 Jun 2026 07:58:08 GMT</lastBuildDate><atom:link href="https://dipan-roy-choudhury.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Sessions, Cookies, and JWT: Which Authentication Should You Use?]]></title><description><![CDATA[When I started building my first full-stack project, I hit a wall almost immediately — how does a server know who I am after I log in?
I kept running into terms like sessions, cookies, and JWT tokens,]]></description><link>https://dipan-roy-choudhury.hashnode.dev/authentication</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/authentication</guid><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Tue, 28 Apr 2026 14:36:22 GMT</pubDate><content:encoded><![CDATA[<p>When I started building my first full-stack project, I hit a wall almost immediately — <em>how does a server know who I am after I log in?</em></p>
<p>I kept running into terms like sessions, cookies, and JWT tokens, and nobody seemed to explain them together in a way that made sense. So in this article, that's exactly what I want to do.</p>
<p>By the end, you'll understand what each one is, how they differ, and — most importantly — <strong>which one to use and when</strong>.</p>
<hr />
<h2>The Core Problem: HTTP is Stateless</h2>
<p>Before anything else, you need to understand <em>why</em> authentication mechanisms even need to exist.</p>
<p>HTTP — the protocol your browser uses to talk to servers — is <strong>stateless</strong>. Every request is independent. The server has no memory of you.</p>
<p>So when you log in and then visit your dashboard, the server has no idea it's still you. From its perspective, it's just getting a random request from somewhere on the internet.</p>
<p>Authentication systems solve this: they give the server a way to <strong>recognize you across multiple requests</strong>.</p>
<hr />
<h2>What Are Sessions?</h2>
<p>A <strong>session</strong> is a way for the server to remember information about a user across requests.</p>
<p>Here's how it works:</p>
<ol>
<li>You log in with your username and password.</li>
<li>The server <strong>verifies your credentials</strong> and creates a session — essentially a record that says <em>"User #42 is logged in"</em> — and stores it in memory or a database.</li>
<li>The server generates a unique <strong>Session ID</strong> (a random string) and sends it back to your browser.</li>
<li>On every subsequent request, your browser sends that Session ID back to the server.</li>
<li>The server looks it up, finds your session data, and knows who you are.</li>
</ol>
<pre><code>Browser                          Server
  |                                |
  |--- POST /login ---------------&gt;|
  |                                | (verifies credentials)
  |                                | (creates session in DB/memory)
  |&lt;-- Set-Cookie: sid=abc123 -----|
  |                                |
  |--- GET /dashboard (sid=abc123)&gt;|
  |                                | (looks up session → "User #42")
  |&lt;-- 200 OK: Dashboard data -----|
</code></pre>
<p>The key point: <strong>the server holds all the data</strong>. The browser only holds a reference (the Session ID) to that data.</p>
<hr />
<h2>What Are Cookies?</h2>
<p>Cookies are the <strong>delivery mechanism</strong> — they're how the Session ID (or any small piece of data) travels back and forth between the browser and server.</p>
<p>A cookie is just a small key-value pair stored in the browser:</p>
<pre><code>sid=abc123xyz; HttpOnly; Secure; SameSite=Strict
</code></pre>
<p>When the server sends a <code>Set-Cookie</code> header, the browser saves it. From that point on, the browser <strong>automatically attaches</strong> that cookie to every request it makes to that domain — you don't have to do anything manually.</p>
<blockquote>
<p>Think of a cookie as a <strong>wristband at an event</strong>. The venue (server) gives it to you at entry (login). Every time you pass a checkpoint (make a request), you show the wristband instead of re-verifying your identity.</p>
</blockquote>
<p>Cookies are not just for sessions. They can store any small piece of data — preferences, tracking info, etc. But in the context of authentication, they're most commonly used to carry the Session ID.</p>
<hr />
<h2>What Are JWT Tokens?</h2>
<p><strong>JWT</strong> stands for <strong>JSON Web Token</strong>. It's an open standard for securely transmitting information between parties as a compact, self-contained string.</p>
<p>A JWT looks like this:</p>
<pre><code>eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQyLCJyb2xlIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
</code></pre>
<p>It has three parts separated by dots:</p>
<pre><code>HEADER . PAYLOAD . SIGNATURE
</code></pre>
<table>
<thead>
<tr>
<th>Part</th>
<th>What it contains</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Header</strong></td>
<td>Algorithm used to sign the token (e.g., HS256)</td>
</tr>
<tr>
<td><strong>Payload</strong></td>
<td>Your actual data — user ID, role, expiry time, etc.</td>
</tr>
<tr>
<td><strong>Signature</strong></td>
<td>A hash that proves the token hasn't been tampered with</td>
</tr>
</tbody></table>
<p>The <strong>payload</strong> is just Base64 encoded, not encrypted — so don't store sensitive data like passwords in it. The <strong>signature</strong> is what makes it trustworthy. It's generated using a secret key that only your server knows.</p>
<p>Here's what a decoded JWT payload looks like:</p>
<pre><code class="language-json">{
  "userId": 42,
  "role": "admin",
  "iat": 1716000000,
  "exp": 1716086400
}
</code></pre>
<p>When you log in, the server creates this token, signs it, and sends it to you. You store it (in <code>localStorage</code> or a cookie) and attach it to every future request — usually in the <code>Authorization</code> header:</p>
<pre><code>Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
</code></pre>
<p>The server receives the token, <strong>verifies the signature</strong>, reads the payload, and knows who you are — <strong>without looking anything up in a database</strong>.</p>
<hr />
<h2>Stateful vs Stateless Authentication</h2>
<p>This is the fundamental difference between sessions and JWT, and it's worth understanding clearly.</p>
<h3>Stateful Authentication (Sessions)</h3>
<p>The server <strong>stores state</strong> — it keeps a record of every active session.</p>
<pre><code>User logs in → Server creates session → Stores it in DB → Gives you an ID
Next request → You send ID → Server looks it up → Finds your data
</code></pre>
<p>The server must maintain and query this session store on every request. The session ID alone is meaningless without the server-side record.</p>
<h3>Stateless Authentication (JWT)</h3>
<p>The server <strong>stores nothing</strong> — all the information is embedded inside the token itself.</p>
<pre><code>User logs in → Server creates JWT with user data → Signs it → Sends it to you
Next request → You send JWT → Server verifies signature → Reads data directly
</code></pre>
<p>No database lookup. No shared state. The token is <strong>self-contained</strong>.</p>
<blockquote>
<p>This is the core trade-off: <strong>stateful = server remembers you</strong>, <strong>stateless = you carry your own proof of identity</strong>.</p>
</blockquote>
<hr />
<h2>Session-Based Auth vs JWT: Full Comparison</h2>
<table>
<thead>
<tr>
<th></th>
<th><strong>Session-Based Auth</strong></th>
<th><strong>JWT-Based Auth</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>Where state lives</strong></td>
<td>Server (DB or memory)</td>
<td>Client (the token itself)</td>
</tr>
<tr>
<td><strong>Server lookup per request</strong></td>
<td>Yes — checks session store</td>
<td>No — just verifies signature</td>
</tr>
<tr>
<td><strong>Scalability</strong></td>
<td>Harder — all servers need access to the same session store</td>
<td>Easier — any server can verify the token independently</td>
</tr>
<tr>
<td><strong>Revocation</strong></td>
<td>Easy — delete the session from the store</td>
<td>Hard — tokens are valid until they expire</td>
</tr>
<tr>
<td><strong>Token size</strong></td>
<td>Small (just an ID)</td>
<td>Larger (carries actual data)</td>
</tr>
<tr>
<td><strong>Storage on client</strong></td>
<td>Cookie (automatic)</td>
<td>localStorage, cookie, or memory</td>
</tr>
<tr>
<td><strong>Best for</strong></td>
<td>Traditional web apps, monoliths</td>
<td>APIs, microservices, mobile apps</td>
</tr>
<tr>
<td><strong>Logout reliability</strong></td>
<td>Instant and guaranteed</td>
<td>Not instant (token remains valid until expiry)</td>
</tr>
</tbody></table>
<hr />
<h2>The Revocation Problem with JWT</h2>
<p>This deserves a separate mention because it catches a lot of developers off guard.</p>
<p>With sessions, <strong>logging out is simple</strong> — you delete the session from the server. The Session ID becomes worthless immediately.</p>
<p>With JWT, you <strong>cannot invalidate a token early</strong>. Once issued, it's valid until it expires. If a user logs out, their token still technically works until the expiry time passes.</p>
<p>Common workarounds:</p>
<ul>
<li><strong>Short expiry times</strong> (e.g., 15 minutes) + a <strong>refresh token</strong> mechanism</li>
<li>Maintaining a <strong>token blacklist</strong> on the server (but now you're adding state back, somewhat defeating the purpose)
This isn't a dealbreaker — it just means JWT logout is a design consideration, not a solved problem out of the box.</li>
</ul>
<hr />
<h2>When to Use Sessions</h2>
<p>Sessions are a solid choice when:</p>
<ul>
<li>You're building a <strong>traditional web application</strong> where the backend renders HTML (like an Express + EJS or Django app).</li>
<li>You need <strong>instant logout</strong> — for example, banking applications, admin panels, or anything security-sensitive where revoking access immediately matters.</li>
<li>Your app runs on a <strong>single server</strong> or a small cluster where sharing a session store (like Redis) is straightforward.</li>
<li>Your users are primarily on <strong>web browsers</strong> (cookies work seamlessly here).</li>
</ul>
<hr />
<h2>When to Use JWT</h2>
<p>JWT makes more sense when:</p>
<ul>
<li>You're building a <strong>REST API</strong> consumed by a mobile app, single-page application (React, Vue, etc.), or third-party clients.</li>
<li>You're working with a <strong>microservices architecture</strong> where multiple independent services need to verify a user's identity without calling a central session store.</li>
<li>You want to <strong>avoid server-side state entirely</strong> for scalability — horizontal scaling becomes trivial because any instance can verify any token.</li>
<li>You need <strong>cross-domain authentication</strong> — JWT works easily across different domains, while cookies have restrictions.</li>
</ul>
<hr />
<h2>A Practical Decision Framework</h2>
<p>If you're staring at a new project and wondering which to pick:</p>
<pre><code>Is your app a traditional server-rendered web app?
  → Use Sessions
 
Is your app a REST API or consumed by mobile clients?
  → Use JWT
 
Do you need instant, guaranteed logout?
  → Use Sessions
 
Are you building microservices or need horizontal scaling?
  → Use JWT
 
Do you need cross-domain auth (e.g., SSO across subdomains)?
  → Use JWT
</code></pre>
<p>And honestly — for many projects, <strong>neither is wrong</strong>. Both are used in production at massive scale. The decision comes down to your architecture, not which one is "better."</p>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><strong>Cookies</strong> — a browser mechanism that stores small data and automatically sends it with every request. Used to carry Session IDs (or tokens).</li>
<li><strong>Sessions</strong> — server-side records of who is logged in. Stateful. Great for traditional apps and when you need reliable logout.</li>
<li><strong>JWT</strong> — self-contained tokens that carry user data and are verified by signature. Stateless. Great for APIs, microservices, and mobile apps.</li>
<li><strong>Stateful</strong> means the server holds your session. <strong>Stateless</strong> means the token holds everything.</li>
<li>The biggest JWT trade-off: <strong>you can't easily revoke a token before it expires</strong>.</li>
</ul>
<hr />
<p>Understanding authentication at this level — not just <em>how</em> to implement it but <em>why</em> each approach exists — is what separates developers who follow tutorials from developers who make architecture decisions.</p>
]]></content:encoded></item><item><title><![CDATA[From Callback Hell to Promises: Understanding Async Code in Node.js]]></title><description><![CDATA[So I've been learning Node.js for a while now, and if there's one concept that confused me the most in the beginning, it was asynchronous code. I kept asking myself — why can't JavaScript just wait fo]]></description><link>https://dipan-roy-choudhury.hashnode.dev/from-callback-hell-to-promises-understanding-async-code-in-node-js</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/from-callback-hell-to-promises-understanding-async-code-in-node-js</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[asynchronous JavaScript]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Tue, 28 Apr 2026 14:14:07 GMT</pubDate><content:encoded><![CDATA[<p>So I've been learning Node.js for a while now, and if there's <strong>one concept that confused me the most in the beginning</strong>, it was asynchronous code. I kept asking myself — <em>why can't JavaScript just wait for things to finish before moving on?</em></p>
<p>In this article, I'll explain everything from scratch — why async code exists, how callbacks work, why they become a nightmare, and how <strong>Promises</strong> ride in to save the day. I'll keep things simple and practical, so let's get into it.</p>
<hr />
<h2>🤔 Why Does Async Code Even Exist?</h2>
<p>Let's start with a real-world scenario.</p>
<p>Imagine you ask Node.js to <strong>read a file</strong> from your disk. Reading a file takes time — maybe a few milliseconds, maybe more if the file is large. Now, JavaScript (and Node.js) runs on a <strong>single thread</strong>, meaning it can only do one thing at a time.</p>
<p>If Node.js just <em>stopped and waited</em> every time it read a file, your entire server would freeze for that duration. Nobody else could make requests. The app would feel completely dead.</p>
<p>That's the problem async code solves.</p>
<blockquote>
<p><strong>Async code lets Node.js say:</strong> <em>"Hey, go read that file. I'll keep doing other stuff. Call me back when you're done."</em></p>
</blockquote>
<p>This is why Node.js is great for I/O-heavy tasks like reading files, making database calls, or hitting APIs — it never just sits there waiting. It keeps moving.</p>
<hr />
<h2>📂 The File Reading Scenario</h2>
<p>Let's use <strong>file reading</strong> as our example throughout this article. It's the most relatable async operation when learning Node.js.</p>
<p>Here's what we want to do:</p>
<ol>
<li>Read a file called <code>user.txt</code></li>
<li>Use the contents of that file to fetch user data</li>
<li>Save the result to another file called <code>result.txt</code>
Simple goal. But as you'll see, <em>how</em> we write this code matters a lot.</li>
</ol>
<hr />
<h2>📞 Callback-Based Async Execution</h2>
<p>Before Promises existed, Node.js handled async operations using <strong>callbacks</strong>.</p>
<p>A callback is just a <strong>function you pass to another function</strong>, telling it: <em>"When you're done, call this function."</em></p>
<p>Here's how reading a file looks with a callback:</p>
<pre><code class="language-js">const fs = require('fs');
 
fs.readFile('user.txt', 'utf8', function(err, data) {
  if (err) {
    console.log('Error reading file:', err);
    return;
  }
  console.log('File contents:', data);
});
 
console.log('This runs first!');
</code></pre>
<h3>Let's break this down step by step:</h3>
<ol>
<li><code>fs.readFile()</code> is called — Node.js kicks off the file reading operation.</li>
<li>Node.js <strong>doesn't wait</strong> for it. It immediately moves to the next line.</li>
<li>So <code>"This runs first!"</code> gets printed <strong>before</strong> the file is even read.</li>
<li>Once the file reading is done, Node.js calls our <strong>callback function</strong> with two arguments:<ul>
<li><code>err</code> — if something went wrong</li>
<li><code>data</code> — the actual file contents
This is the classic <strong>error-first callback pattern</strong> in Node.js. The first argument is always the error.</li>
</ul>
</li>
</ol>
<blockquote>
<p>This flow is called the <strong>Event Loop</strong> in action — Node.js registers the callback, goes back to doing other work, and comes back to execute the callback when the operation completes.</p>
</blockquote>
<p>Callbacks work. But things get ugly fast.</p>
<hr />
<h2>😱 The Problem: Callback Hell</h2>
<p>Now let's go back to our goal — read a file, fetch user data based on it, then save the result.</p>
<p>With callbacks, this is how it looks:</p>
<pre><code class="language-js">const fs = require('fs');
 
fs.readFile('user.txt', 'utf8', function(err, userId) {
  if (err) {
    console.log('Error reading user file:', err);
    return;
  }
 
  // Now fetch user data using the userId
  fetchUserData(userId, function(err, userData) {
    if (err) {
      console.log('Error fetching user data:', err);
      return;
    }
 
    // Now save the result
    fs.writeFile('result.txt', userData, function(err) {
      if (err) {
        console.log('Error writing result:', err);
        return;
      }
 
      console.log('Done! Result saved successfully.');
    });
  });
});
</code></pre>
<p>Look at that indentation. Every new async step forces you to go <strong>one level deeper</strong> into the nesting.</p>
<p>This pattern has a famous name in the JavaScript world:</p>
<blockquote>
<h3>😈 Callback Hell (also called the "Pyramid of Doom")</h3>
</blockquote>
<h3>Why is this a problem?</h3>
<table>
<thead>
<tr>
<th>Problem</th>
<th>What it means</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Hard to read</strong></td>
<td>Your eyes have to track multiple levels of nesting</td>
</tr>
<tr>
<td><strong>Hard to debug</strong></td>
<td>Finding where an error came from is painful</td>
</tr>
<tr>
<td><strong>Hard to maintain</strong></td>
<td>Adding a new step means touching deeply nested code</td>
</tr>
<tr>
<td><strong>Error handling is repetitive</strong></td>
<td>You write <code>if (err) return</code> at <em>every single level</em></td>
</tr>
</tbody></table>
<p>Imagine 6-7 async steps chained like this. Your code becomes a triangle pointing to the right — practically unreadable.</p>
<p>There had to be a better way. And there was.</p>
<hr />
<h2>🤝 Promise-Based Async Handling</h2>
<p>Introduced in <strong>ES6 (2015)</strong>, Promises gave us a cleaner way to handle async operations.</p>
<p>A <strong>Promise</strong> is an object that represents the <strong>eventual result</strong> of an async operation. It can be in one of three states:</p>
<ul>
<li><strong>Pending</strong> — the operation is still running</li>
<li><strong>Fulfilled</strong> — the operation completed successfully</li>
<li><strong>Rejected</strong> — the operation failed
Here's the same file reading, but now using Promises:</li>
</ul>
<pre><code class="language-js">const fs = require('fs').promises;
 
fs.readFile('user.txt', 'utf8')
  .then(function(userId) {
    return fetchUserData(userId); // returns a Promise
  })
  .then(function(userData) {
    return fs.writeFile('result.txt', userData);
  })
  .then(function() {
    console.log('Done! Result saved successfully.');
  })
  .catch(function(err) {
    console.log('Something went wrong:', err);
  });
</code></pre>
<p>That's it. Flat. Clean. Readable.</p>
<h3>How does <code>.then()</code> and <code>.catch()</code> work?</h3>
<ul>
<li><code>.then()</code> runs when the Promise <strong>resolves</strong> (succeeds). Whatever you <code>return</code> from a <code>.then()</code> becomes the input for the <em>next</em> <code>.then()</code>.</li>
<li><code>.catch()</code> runs when <strong>any</strong> Promise in the chain <strong>rejects</strong> (fails). One single error handler for the entire chain.
This chaining is possible because <code>.then()</code> <strong>always returns a new Promise</strong>, which is why you can keep chaining them.</li>
</ul>
<hr />
<h2>✨ Creating Your Own Promise</h2>
<p>If you're wrapping an older callback-based function into a Promise yourself, here's how you do it:</p>
<pre><code class="language-js">function readFilePromise(filename) {
  return new Promise(function(resolve, reject) {
    fs.readFile(filename, 'utf8', function(err, data) {
      if (err) {
        reject(err); // Something went wrong
      } else {
        resolve(data); // All good, pass the data
      }
    });
  });
}
 
// Now you can use it like:
readFilePromise('user.txt')
  .then(data =&gt; console.log('File data:', data))
  .catch(err =&gt; console.log('Error:', err));
</code></pre>
<p>The <code>new Promise()</code> constructor takes a function with two arguments:</p>
<ul>
<li><code>resolve</code> — call this when the operation succeeds</li>
<li><code>reject</code> — call this when the operation fails</li>
</ul>
<hr />
<h2>⚡ Bonus: async/await (Promises, but Even Cleaner)</h2>
<p>Once you understand Promises, <code>async/await</code> is just <strong>syntactic sugar</strong> on top of them. It makes your async code look like normal synchronous code:</p>
<pre><code class="language-js">const fs = require('fs').promises;
 
async function processUser() {
  try {
    const userId = await fs.readFile('user.txt', 'utf8');
    const userData = await fetchUserData(userId);
    await fs.writeFile('result.txt', userData);
    console.log('Done! Result saved successfully.');
  } catch (err) {
    console.log('Something went wrong:', err);
  }
}
 
processUser();
</code></pre>
<p><code>await</code> simply <strong>pauses execution inside an async function</strong> until the Promise resolves. Under the hood, it's still using Promises — just written in a way that's even easier to read.</p>
<hr />
<h2>📊 Callback vs Promise: Side-by-Side Comparison</h2>
<p>Let's put both approaches side by side so the difference is crystal clear:</p>
<h3>Callback approach:</h3>
<pre><code class="language-js">fs.readFile('user.txt', 'utf8', function(err, userId) {
  if (err) return handleError(err);
  fetchUserData(userId, function(err, userData) {
    if (err) return handleError(err);
    fs.writeFile('result.txt', userData, function(err) {
      if (err) return handleError(err);
      console.log('Done!');
    });
  });
});
</code></pre>
<h3>Promise approach:</h3>
<pre><code class="language-js">fs.readFile('user.txt', 'utf8')
  .then(userId =&gt; fetchUserData(userId))
  .then(userData =&gt; fs.writeFile('result.txt', userData))
  .then(() =&gt; console.log('Done!'))
  .catch(handleError);
</code></pre>
<p>Same logic. Completely different readability.</p>
<hr />
<h2>🏆 Benefits of Promises (Summary)</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Callbacks</th>
<th>Promises</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Readability</strong></td>
<td>Nested, hard to follow</td>
<td>Flat chain, easy to read</td>
</tr>
<tr>
<td><strong>Error Handling</strong></td>
<td><code>if (err)</code> at every level</td>
<td>Single <code>.catch()</code> for all</td>
</tr>
<tr>
<td><strong>Chaining</strong></td>
<td>Ugly nesting</td>
<td>Clean <code>.then()</code> chain</td>
</tr>
<tr>
<td><strong>Composability</strong></td>
<td>Difficult</td>
<td><code>Promise.all()</code>, <code>Promise.race()</code> etc.</td>
</tr>
<tr>
<td><strong>Debugging</strong></td>
<td>Hard to trace</td>
<td>Stack traces are cleaner</td>
</tr>
</tbody></table>
<hr />
<h2>🎯 Wrapping Up</h2>
<p>Here's the big picture:</p>
<ul>
<li>Node.js is <strong>single-threaded</strong>, so it uses async code to avoid blocking.</li>
<li><strong>Callbacks</strong> were the original way to handle async — they work, but nest deeply and become hard to manage.</li>
<li><strong>Promises</strong> solve this with a clean <code>.then()/.catch()</code> chain — one error handler, no nesting.</li>
<li><strong>async/await</strong> is the modern, cleanest way to write Promise-based code.
If you're just getting started with Node.js, my suggestion is: understand callbacks first (so you know <em>why</em> Promises exist), then move to Promises, and eventually make <code>async/await</code> your default.</li>
</ul>
<p>The journey from callback hell to clean async code is one of the most satisfying things about growing as a Node.js developer. Trust me on that one.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Linux File System Hunting]]></title><description><![CDATA[Most people learn Linux by memorizing commands. I decided to do something different — I went hunting.
Instead of running ls and mkdir in a terminal for the hundredth time, I decided to actually open u]]></description><link>https://dipan-roy-choudhury.hashnode.dev/linux-file-system-hunting</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/linux-file-system-hunting</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Linux]]></category><category><![CDATA[linux-file-system]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 22 Apr 2026 07:39:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68dec390645cffce7a10a7d9/73c04a42-849e-4002-979f-92843aeeef12.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Most people learn Linux by memorizing commands. I decided to do something different — I went hunting.</em></p>
<p>Instead of running <code>ls</code> and <code>mkdir</code> in a terminal for the hundredth time, I decided to actually open up the Linux file system and ask: <em>what's really going on here?</em> What do these folders actually do? Why do they exist? What problems are they solving?</p>
<p>What followed was one of the most eye-opening afternoons I've had as a CS student. Here's what I discovered.</p>
<hr />
<h2>1. <code>/etc</code> — The Brain of the Entire System</h2>
<p>I always knew <code>/etc</code> existed. I never knew it was basically the <strong>control room</strong> of Linux.</p>
<p>Almost every configuration file that decides how your system behaves lives here. Want to change how your system resolves domain names? <code>/etc/hosts</code>. Want to control who can log in? <code>/etc/passwd</code> and <code>/etc/shadow</code>. Want to define your hostname? <code>/etc/hostname</code>.</p>
<pre><code class="language-bash">cat /etc/hostname
</code></pre>
<p>What blew my mind was realizing that <code>/etc</code> doesn't contain programs — it contains <strong>instructions for programs</strong>. Every service running on your Linux machine comes to <code>/etc</code> to understand its own rules. It's a convention — not enforced by the kernel — but universally followed.</p>
<p>The name itself comes from old Unix terminology meaning "et cetera," but practically, it means: <em>everything that doesn't belong anywhere else but is critical to how the system runs</em>.</p>
<blockquote>
<p><strong>Why it matters:</strong> If you ever need to debug why something behaves a certain way on Linux, <code>/etc</code> is always your first stop.</p>
</blockquote>
<hr />
<h2>2. <code>/etc/resolv.conf</code> — How Your System Actually Resolves DNS</h2>
<p>I typed <code>google.com</code> in a browser and wondered: how does my machine know where that actually is? The answer lives in one small file:</p>
<pre><code class="language-bash">cat /etc/resolv.conf
</code></pre>
<p>This file tells your system which <strong>DNS nameserver</strong> to contact when it needs to resolve a domain name. On most modern systems, you'll see something like:</p>
<pre><code>nameserver 127.0.0.53
</code></pre>
<p>That's not Google's DNS. That's <code>systemd-resolved</code> — a local DNS stub running on your own machine. Your system first talks to <em>itself</em>, which then forwards the query upstream.</p>
<pre><code class="language-bash">resolvectl status
</code></pre>
<p>Running this shows you the actual upstream DNS servers in use — often assigned by your router via DHCP. What I found genuinely interesting: the DNS resolution chain is:</p>
<pre><code>browser → local stub (127.0.0.53) → ISP or custom DNS → root nameservers
</code></pre>
<p>That single file is the entry point to that entire chain.</p>
<blockquote>
<p><strong>Why it matters:</strong> If your internet is working but domain names aren't resolving, this file is why. It's also why changing DNS (to Cloudflare's <code>1.1.1.1</code> or Google's <code>8.8.8.8</code>) can speed up your browsing.</p>
</blockquote>
<hr />
<h2>3. <code>/etc/hosts</code> — DNS That Existed Before DNS</h2>
<p>Before the internet had a proper DNS system, every machine on the network maintained a file mapping hostnames to IP addresses. That file still exists today:</p>
<pre><code class="language-bash">cat /etc/hosts
</code></pre>
<p>You'll see entries like:</p>
<pre><code>127.0.0.1   localhost
::1         localhost
</code></pre>
<p>Your machine checks this file <strong>before</strong> querying any DNS server. That order is defined in <code>/etc/nsswitch.conf</code> — where <code>files</code> (i.e., <code>/etc/hosts</code>) comes before <code>dns</code>.</p>
<p>This means you can map any domain to any IP locally. Developers use this to point <code>myapp.local</code> to <code>127.0.0.1</code>. Sysadmins use it for internal services. And historically, malware would modify this file to redirect legitimate domains to malicious IPs — which is why monitoring it matters from a <strong>security</strong> perspective.</p>
<blockquote>
<p><strong>The insight:</strong> A file designed in the early days of ARPANET is still actively consulted by your browser every single time you load a website.</p>
</blockquote>
<hr />
<h2>4. <code>/proc</code> — A Filesystem That Doesn't Actually Exist on Disk</h2>
<p>This one genuinely surprised me. <code>/proc</code> looks like a folder full of files, but none of those files physically exist on your hard drive. They are <strong>generated in real-time by the kernel</strong> every time you read them.</p>
<pre><code class="language-bash">cat /proc/cpuinfo
</code></pre>
<p>This gives you live information about your CPU — cores, model name, flags. But there's no <code>cpuinfo</code> file sitting on disk. The kernel fabricates it the moment you ask.</p>
<pre><code class="language-bash">cat /proc/meminfo
</code></pre>
<p>Same for memory usage. Everything is <strong>live</strong>.</p>
<p>What's really interesting is <code>/proc/&lt;PID&gt;/</code> — for every running process, there's a directory named after its Process ID. Inside:</p>
<pre><code class="language-bash">cat /proc/1/status
</code></pre>
<p>Process <code>1</code> is <code>systemd</code> — the first process your system starts. Inside its <code>/proc</code> directory, you can see its memory usage, its state, which user it's running as, and even its open file descriptors.</p>
<pre><code class="language-bash">ls -la /proc/1/fd
</code></pre>
<p><code>fd</code> shows every file currently open by that process. This is exactly how tools like <code>lsof</code> work — they're just reading <code>/proc</code> under the hood.</p>
<blockquote>
<p><strong>Why it matters:</strong> <code>/proc</code> is the window through which the kernel exposes its internals to userspace. It's how monitoring tools, debuggers, and sysadmins understand what's actually running on a machine.</p>
</blockquote>
<hr />
<h2>5. <code>/proc/net/route</code> — The Routing Table Hidden in Plain Sight</h2>
<p>I knew routers had routing tables. I didn't know my own Linux machine did too.</p>
<pre><code class="language-bash">cat /proc/net/route
</code></pre>
<p>The output looks like hex gibberish at first:</p>
<pre><code>Iface   Destination  Gateway   Flags  ...
eth0    00000000     0101A8C0  0003   ...
</code></pre>
<p>But once you decode it (it's little-endian hex), <code>0101A8C0</code> becomes <code>192.168.1.1</code> — your <strong>default gateway</strong>. The <code>00000000</code> destination means "everything else" — the default route.</p>
<p>A more human-readable version:</p>
<pre><code class="language-bash">ip route show
</code></pre>
<p>What I realized: every time your machine sends a packet, it consults this table to decide <em>where to send it</em>. If the destination is on your local network — send directly. Otherwise — send to the gateway. This decision happens <strong>at the kernel level</strong>, every single time, for every single packet.</p>
<blockquote>
<p><strong>The insight:</strong> Your Linux machine is essentially a router for itself. The routing table isn't just a networking concept — it's a live kernel data structure exposed through <code>/proc</code>.</p>
</blockquote>
<hr />
<h2>6. <code>/etc/passwd</code> and <code>/etc/shadow</code> — The Split Security Design</h2>
<p>When I first ran:</p>
<pre><code class="language-bash">cat /etc/passwd
</code></pre>
<p>I expected to see passwords. Instead I saw entries like:</p>
<pre><code>dipan:x:1000:1000:,,,:/home/dipan:/bin/bash
</code></pre>
<p>That <code>x</code> where the password should be? It means the actual password hash is stored <em>elsewhere</em> — in <code>/etc/shadow</code>:</p>
<pre><code class="language-bash">sudo cat /etc/shadow
</code></pre>
<p>The entries here look like:</p>
<pre><code>dipan:\(6\)rounds=...$&lt;long hash&gt;:19500:0:99999:7:::
</code></pre>
<p>This split exists for a <strong>critical security reason</strong>: <code>/etc/passwd</code> needs to be readable by everyone (many programs use it to map user IDs to names), but passwords obviously shouldn't be. So Linux separates them — <code>/etc/shadow</code> is readable only by <code>root</code>.</p>
<p>The hash prefix itself (<code>\(6\)</code>) tells you the algorithm used — <code>\(6\)</code> means <strong>SHA-512</strong>. The numbers after the hash encode the password's age, expiry policy, and warning period — a full password lifecycle management system packed into one line.</p>
<blockquote>
<p><strong>Why it matters:</strong> This design is a real-world lesson in the <strong>principle of least privilege</strong> — give each file only the permissions it absolutely needs.</p>
</blockquote>
<hr />
<h2>7. <code>/var/log</code> — The System's Memory</h2>
<p>If your system misbehaves, <code>/var/log</code> is where it leaves a trail:</p>
<pre><code class="language-bash">ls /var/log
</code></pre>
<p>You'll find files like <code>syslog</code>, <code>auth.log</code>, <code>kern.log</code>, <code>dpkg.log</code>, and more.</p>
<pre><code class="language-bash">tail -f /var/log/syslog
</code></pre>
<p>Watching this <strong>live</strong> is fascinating. Every kernel event, every daemon starting or crashing, every network change — it flows through here in real time.</p>
<p>The <code>auth.log</code> specifically records every login attempt — successful or not:</p>
<pre><code class="language-bash">grep "Failed password" /var/log/auth.log
</code></pre>
<p>On any internet-exposed machine, this is almost always full of <strong>brute-force SSH attempts</strong> from bots trying common username/password combos. Seeing it for the first time is a bit unsettling — and a good reminder of why strong passwords (or key-based auth) matter.</p>
<p>On modern systemd-based systems, there's also:</p>
<pre><code class="language-bash">journalctl -xe
</code></pre>
<p>This queries the <strong>binary journal</strong> — a structured, indexed log format that allows filtering by service, time range, or priority in ways plain text logs can't match.</p>
<blockquote>
<p><strong>The insight:</strong> Logs aren't just for debugging. They're a <strong>forensic timeline</strong>. If something goes wrong on a Linux system, <code>/var/log</code> is often the only witness.</p>
</blockquote>
<hr />
<h2>8. <code>/etc/systemd/system</code> — How Services Actually Start</h2>
<p>I always used <code>systemctl start nginx</code> without thinking about what that actually does. The answer is in:</p>
<pre><code class="language-bash">cat /lib/systemd/system/ssh.service
</code></pre>
<p>A <code>.service</code> file is a plain text description of how a service should behave:</p>
<pre><code class="language-ini">[Unit]
Description=OpenBSD Secure Shell server
After=network.target
 
[Service]
ExecStart=/usr/sbin/sshd -D
Restart=on-failure
 
[Install]
WantedBy=multi-user.target
</code></pre>
<p>This single file tells systemd:</p>
<ul>
<li>Start <strong>after</strong> the network is up</li>
<li>Run <strong>this binary</strong></li>
<li>If it crashes — <strong>restart it automatically</strong></li>
<li><code>WantedBy=multi-user.target</code> → start this at boot when the system reaches normal multi-user mode
What I found interesting: dependencies between services are declared right here in plain text. <code>systemd</code> builds a full <strong>dependency graph</strong> at boot and starts services in the correct order — or in parallel when possible, making boot times faster.</li>
</ul>
<blockquote>
<p><strong>Why it matters:</strong> Understanding <code>.service</code> files means you can write your own. Any script or program can become a managed system service with automatic restart, logging, and boot integration.</p>
</blockquote>
<hr />
<h2>9. <code>/dev</code> — Where Hardware Becomes a File</h2>
<p>Linux follows one core philosophy: <strong>everything is a file</strong>. Nowhere is this more literal than <code>/dev</code>:</p>
<pre><code class="language-bash">ls /dev
</code></pre>
<p>You'll see entries like <code>sda</code>, <code>sdb</code> (your disks), <code>tty0</code>, <code>tty1</code> (terminals), <code>null</code>, <code>zero</code>, <code>random</code>, and <code>urandom</code>.</p>
<table>
<thead>
<tr>
<th>Device</th>
<th>What it does</th>
</tr>
</thead>
<tbody><tr>
<td><code>/dev/null</code></td>
<td>Write anything here and it disappears. It's the void. Used to suppress output in scripts.</td>
</tr>
<tr>
<td><code>/dev/zero</code></td>
<td>Read from this and you get an infinite stream of zero bytes. Used to create blank files or wipe disks.</td>
</tr>
<tr>
<td><code>/dev/urandom</code></td>
<td>Read from this and you get cryptographically random bytes — used internally to generate encryption keys and session tokens.</td>
</tr>
</tbody></table>
<pre><code class="language-bash">head -c 16 /dev/urandom | base64
</code></pre>
<p>That gives you 16 bytes of raw randomness you can use as a random token. The entropy for this comes from <strong>hardware events</strong> — disk timings, keyboard interrupts, network packet arrival times.</p>
<blockquote>
<p><strong>The insight:</strong> The disk your OS runs on (<code>/dev/sda</code>) is just a file. The terminal you're typing into (<code>/dev/tty</code>) is just a file. This abstraction is what makes Linux both powerful and philosophically elegant.</p>
</blockquote>
<hr />
<h2>10. <code>/boot</code> — The Moment Before Linux Exists</h2>
<p>Before the kernel runs, something has to load it. That's what <code>/boot</code> is for:</p>
<pre><code class="language-bash">ls /boot
</code></pre>
<p>You'll typically find:</p>
<ul>
<li><strong><code>vmlinuz</code></strong> — The compressed Linux kernel itself</li>
<li><strong><code>initrd.img</code></strong> — An initial RAM disk — a tiny temporary filesystem loaded into memory before the real filesystem is mounted</li>
<li><strong><code>grub/</code></strong> — The GRUB bootloader config</li>
</ul>
<pre><code class="language-bash">cat /boot/grub/grub.cfg
</code></pre>
<p>This file tells GRUB what OS options to show you and which kernel to load. If you've ever dual-booted Linux and Windows, <strong>this file controls that menu</strong>.</p>
<p>The <code>initrd.img</code> especially fascinated me — it's a complete minimal Linux environment packed into a single file. When your machine boots, the kernel first unpacks this into RAM, uses it to load the necessary drivers to access your actual disk, then mounts the real filesystem and hands over control.</p>
<blockquote>
<p><strong>The insight:</strong> The Linux boot process is a relay race:</p>
<pre><code>BIOS/UEFI → GRUB → initrd → kernel → systemd → your desktop
</code></pre>
<p><code>/boot</code> contains the first three handoffs.</p>
</blockquote>
<hr />
<h2>What This Hunt Taught Me</h2>
<p>Going through the Linux file system this way — not to run commands, but to <em>understand</em> — completely changed how I see an OS.</p>
<p>Linux doesn't hide its internals. <strong>Everything is a file.</strong> Everything is readable (with the right permissions). The kernel exposes itself through <code>/proc</code>. Services declare their own behavior in plain text. Logs record everything.</p>
<p>The more you look, the more you realize Linux is not a black box — it's a <strong>transparent machine</strong> that trusts you to understand it, if you're willing to look.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Map and Set in JavaScript]]></title><description><![CDATA[JavaScript provides several built-in data structures for storing and managing data. Traditionally, developers relied on objects and arrays for most tasks. However, modern JavaScript introduced two pow]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-map-and-set-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-map-and-set-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[map]]></category><category><![CDATA[set]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 19:02:47 GMT</pubDate><content:encoded><![CDATA[<p>JavaScript provides several built-in data structures for storing and managing data. Traditionally, developers relied on <strong>objects and arrays</strong> for most tasks. However, modern JavaScript introduced two powerful structures: <strong>Map</strong> and <strong>Set</strong>.</p>
<p>These structures solve some limitations of objects and arrays and provide more flexibility when working with collections of data.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What <code>Map</code> is</p>
</li>
<li><p>What <code>Set</code> is</p>
</li>
<li><p>The difference between Map and Object</p>
</li>
<li><p>The difference between Set and Array</p>
</li>
<li><p>When to use Map and Set</p>
</li>
</ul>
<hr />
<h2>Problems with Traditional Objects and Arrays</h2>
<p>Before understanding Map and Set, it helps to see some limitations of objects and arrays.</p>
<h3>Objects</h3>
<p>Objects are often used for storing <strong>key-value pairs</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};
</code></pre>
<p>However, objects have some limitations:</p>
<ul>
<li><p>Keys are automatically converted to strings</p>
</li>
<li><p>Objects are not designed specifically for key-value collection operations</p>
</li>
<li><p>Iteration over objects is less straightforward</p>
</li>
</ul>
<hr />
<h3>Arrays</h3>
<p>Arrays are useful for storing lists of values.</p>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4];
</code></pre>
<p>However, arrays allow <strong>duplicate values</strong>, which may not always be desirable.</p>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 2, 3];
</code></pre>
<p>Sometimes we need a structure where <strong>each value is unique</strong>, and this is where <code>Set</code> becomes useful.</p>
<hr />
<h2>What Is a Map?</h2>
<p>A <strong>Map</strong> is a data structure used to store <strong>key-value pairs</strong>, similar to objects, but with more flexibility.</p>
<p>Example:</p>
<pre><code class="language-javascript">const userMap = new Map();

userMap.set("name", "Dipan");
userMap.set("age", 21);

console.log(userMap.get("name"));
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Dipan
</code></pre>
<p>Key features of Map:</p>
<ul>
<li><p>Keys can be <strong>any data type</strong></p>
</li>
<li><p>Maintains insertion order</p>
</li>
<li><p>Designed specifically for key-value storage</p>
</li>
</ul>
<hr />
<h2>Map Example</h2>
<pre><code class="language-javascript">const map = new Map();

map.set("city", "Kolkata");
map.set("country", "India");

console.log(map);
</code></pre>
<p>Retrieving values:</p>
<pre><code class="language-javascript">console.log(map.get("city"));
</code></pre>
<hr />
<h2>Difference Between Map and Object</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Object</th>
<th>Map</th>
</tr>
</thead>
<tbody><tr>
<td>Key types</td>
<td>Strings or symbols</td>
<td>Any data type</td>
</tr>
<tr>
<td>Order</td>
<td>Not guaranteed</td>
<td>Maintains insertion order</td>
</tr>
<tr>
<td>Built for key-value storage</td>
<td>General structure</td>
<td>Designed specifically for it</td>
</tr>
<tr>
<td>Size property</td>
<td>Not directly available</td>
<td><code>map.size</code></td>
</tr>
</tbody></table>
<p>Example showing flexible keys:</p>
<pre><code class="language-javascript">const map = new Map();

map.set(1, "number key");
map.set(true, "boolean key");
map.set({ id: 1 }, "object key");
</code></pre>
<p>Objects cannot easily support such flexible keys.</p>
<hr />
<h2>What Is a Set?</h2>
<p>A <strong>Set</strong> is a collection of <strong>unique values</strong>.</p>
<p>This means duplicate values are automatically removed.</p>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = new Set([1, 2, 2, 3, 4]);

console.log(numbers);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Set(4) {1, 2, 3, 4}
</code></pre>
<p>Even though <code>2</code> appeared twice, the set only stores it once.</p>
<hr />
<h2>Set Example</h2>
<p>Adding values to a set:</p>
<pre><code class="language-javascript">const set = new Set();

set.add(1);
set.add(2);
set.add(2);
set.add(3);

console.log(set);
</code></pre>
<p>Removing values:</p>
<pre><code class="language-javascript">set.delete(2);
</code></pre>
<p>Checking existence:</p>
<pre><code class="language-javascript">console.log(set.has(1));
</code></pre>
<hr />
<h2>Difference Between Set and Array</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Array</th>
<th>Set</th>
</tr>
</thead>
<tbody><tr>
<td>Duplicate values</td>
<td>Allowed</td>
<td>Not allowed</td>
</tr>
<tr>
<td>Access by index</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Main use</td>
<td>Ordered list</td>
<td>Unique collection</td>
</tr>
</tbody></table>
<p>Example comparison:</p>
<h3>Array</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 2, 3];
</code></pre>
<p>Duplicates remain.</p>
<hr />
<h3>Set</h3>
<pre><code class="language-javascript">const numbers = new Set([1, 2, 2, 3]);
</code></pre>
<p>Duplicates are removed automatically.</p>
<hr />
<h2>Practical Use Cases</h2>
<h3>Removing Duplicate Values</h3>
<p>Sets are commonly used to remove duplicates.</p>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 2, 3, 4];

const uniqueNumbers = [...new Set(numbers)];

console.log(uniqueNumbers);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, 3, 4]
</code></pre>
<hr />
<h3>Storing Key-Value Data Efficiently</h3>
<p>Maps are useful when working with dynamic key-value data.</p>
<p>Example:</p>
<pre><code class="language-javascript">const userRoles = new Map();

userRoles.set("admin", "full access");
userRoles.set("editor", "edit content");
userRoles.set("viewer", "read only");
</code></pre>
<hr />
<h2>When to Use Map and Set</h2>
<h3>Use Map when:</h3>
<ul>
<li><p>You need flexible <strong>key-value storage</strong></p>
</li>
<li><p>Keys are not limited to strings</p>
</li>
<li><p>You frequently add or remove entries</p>
</li>
</ul>
<hr />
<h3>Use Set when:</h3>
<ul>
<li><p>You need <strong>unique values</strong></p>
</li>
<li><p>You want to remove duplicates easily</p>
</li>
<li><p>You need fast existence checks</p>
</li>
</ul>
<hr />
<h2>Conclusion</h2>
<p>Map and Set are powerful data structures introduced in modern JavaScript that provide better ways to manage collections of data.</p>
<p>Key points to remember:</p>
<ul>
<li><p><strong>Map</strong> stores key-value pairs with flexible key types</p>
</li>
<li><p><strong>Set</strong> stores unique values only</p>
</li>
<li><p>Map is more flexible than objects for key-value storage</p>
</li>
<li><p>Set is useful for handling collections without duplicates</p>
</li>
<li><p>Both structures solve common limitations of traditional objects and arrays</p>
</li>
</ul>
<p>Understanding when and how to use Map and Set will help you write more efficient and organized JavaScript code.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding this in JavaScript]]></title><description><![CDATA[One concept that often confuses JavaScript beginners is the this keyword. Unlike many other programming languages, the value of this in JavaScript depends on how a function is called, not where it is ]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-this-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-this-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[this keyword]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:39:44 GMT</pubDate><content:encoded><![CDATA[<p>One concept that often confuses JavaScript beginners is the <code>this</code> <strong>keyword</strong>. Unlike many other programming languages, the value of <code>this</code> in JavaScript depends on <strong>how a function is called</strong>, not where it is defined.</p>
<p>Understanding <code>this</code> is important because it is frequently used when working with objects, methods, and event handlers.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What <code>this</code> represents</p>
</li>
<li><p><code>this</code> in the global context</p>
</li>
<li><p><code>this</code> inside objects</p>
</li>
<li><p><code>this</code> inside functions</p>
</li>
<li><p>How the calling context changes the value of <code>this</code></p>
</li>
</ul>
<hr />
<h2>What Does <code>this</code> Represent?</h2>
<p>In simple terms, <code>this</code> <strong>refers to the object that is calling the function</strong>.</p>
<p>You can think of it as:</p>
<pre><code class="language-plaintext">this → the caller of the function
</code></pre>
<p>The value of <code>this</code> is determined <strong>at the time the function is executed</strong>, not when it is written.</p>
<hr />
<h2><code>this</code> in the Global Context</h2>
<p>When <code>this</code> is used in the global scope, it refers to the <strong>global object</strong>.</p>
<p>Example in a browser environment:</p>
<pre><code class="language-javascript">console.log(this);
</code></pre>
<p>In browsers, the output is typically:</p>
<pre><code class="language-plaintext">window
</code></pre>
<p>This means the global object (window) is the value of <code>this</code>.</p>
<hr />
<h2><code>this</code> Inside Objects</h2>
<p>When a function is called as a <strong>method of an object</strong>, <code>this</code> refers to that object.</p>
<p>Example:</p>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  greet: function () {
    console.log("Hello, my name is " + this.name);
  }
};

user.greet();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, my name is Dipan
</code></pre>
<p>Explanation:</p>
<ul>
<li><p>The function <code>greet</code> is called using <code>user.greet()</code></p>
</li>
<li><p>Therefore, <code>this</code> <strong>refers to</strong> <code>user</code></p>
</li>
</ul>
<hr />
<h2><code>this</code> Inside Regular Functions</h2>
<p>When a function is called normally (not as part of an object), <code>this</code> behaves differently.</p>
<p>Example:</p>
<pre><code class="language-javascript">function showThis() {
  console.log(this);
}

showThis();
</code></pre>
<p>In browsers (non-strict mode), the output is usually:</p>
<pre><code class="language-plaintext">window
</code></pre>
<p>This happens because the function is called in the global context.</p>
<hr />
<h2>How Calling Context Changes <code>this</code></h2>
<p>The most important rule about <code>this</code> is:</p>
<pre><code class="language-plaintext">The value of `this` depends on how the function is called.
</code></pre>
<p>Consider this example:</p>
<pre><code class="language-javascript">const person = {
  name: "Dipan",
  sayName: function () {
    console.log(this.name);
  }
};

person.sayName();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Dipan
</code></pre>
<p>Here, <code>this</code> refers to <code>person</code>.</p>
<hr />
<p>Now consider this variation:</p>
<pre><code class="language-javascript">const person = {
  name: "Dipan",
  sayName: function () {
    console.log(this.name);
  }
};

const anotherFunction = person.sayName;

anotherFunction();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">undefined
</code></pre>
<p>Explanation:</p>
<ul>
<li><p>The function is no longer called as <code>person.sayName()</code></p>
</li>
<li><p>It is called independently</p>
</li>
<li><p>Therefore, <code>this</code> no longer refers to <code>person</code></p>
</li>
</ul>
<p>This demonstrates that <strong>the caller determines the value of</strong> <code>this</code>.</p>
<hr />
<h2>Simple Rule to Remember</h2>
<p>A useful way to think about <code>this</code> is:</p>
<pre><code class="language-plaintext">Look at the object before the dot when the function is called.
</code></pre>
<p>Example:</p>
<pre><code class="language-javascript">object.method()
</code></pre>
<p>In this case:</p>
<pre><code class="language-plaintext">this → object
</code></pre>
<hr />
<h2>Why Understanding <code>this</code> Is Important</h2>
<p>The <code>this</code> keyword appears frequently in JavaScript when working with:</p>
<ul>
<li><p>Object methods</p>
</li>
<li><p>Event handlers</p>
</li>
<li><p>Constructor functions</p>
</li>
<li><p>Classes</p>
</li>
</ul>
<p>Understanding how <code>this</code> works helps avoid unexpected behavior and makes object-oriented JavaScript easier to work with.</p>
<hr />
<h2>Conclusion</h2>
<p>The <code>this</code> keyword in JavaScript refers to the <strong>object that calls a function</strong>, and its value depends on how the function is executed.</p>
<p>Key points to remember:</p>
<ul>
<li><p><code>this</code> represents the caller of a function</p>
</li>
<li><p>In the global context, it refers to the global object</p>
</li>
<li><p>Inside object methods, <code>this</code> refers to the object itself</p>
</li>
<li><p>Inside regular functions, <code>this</code> often refers to the global object</p>
</li>
<li><p>The calling context determines the value of <code>this</code></p>
</li>
</ul>
<p>By understanding how <code>this</code> changes based on the calling context, you can write clearer and more predictable JavaScript code.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Destructuring in JavaScript]]></title><description><![CDATA[When working with arrays and objects in JavaScript, you often need to extract values and assign them to variables. Doing this manually can lead to repetitive and less readable code.
To solve this, Jav]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-destructuring-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-destructuring-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Destructuring]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:33:07 GMT</pubDate><content:encoded><![CDATA[<p>When working with arrays and objects in JavaScript, you often need to extract values and assign them to variables. Doing this manually can lead to repetitive and less readable code.</p>
<p>To solve this, JavaScript provides a feature called <strong>destructuring</strong>, which allows you to extract values from arrays and objects in a clean and concise way.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What destructuring means</p>
</li>
<li><p>Destructuring arrays</p>
</li>
<li><p>Destructuring objects</p>
</li>
<li><p>Default values</p>
</li>
<li><p>Benefits of destructuring</p>
</li>
</ul>
<hr />
<h2>What Is Destructuring?</h2>
<p><strong>Destructuring</strong> is a syntax in JavaScript that allows you to unpack values from arrays or properties from objects into separate variables.</p>
<p>Instead of accessing values one by one, destructuring lets you extract them in a single statement.</p>
<hr />
<h2>Destructuring Arrays</h2>
<h3>Without Destructuring</h3>
<pre><code class="language-javascript">const numbers = [10, 20, 30];

const first = numbers[0];
const second = numbers[1];
const third = numbers[2];
</code></pre>
<p>This approach works, but it is repetitive.</p>
<hr />
<h3>With Destructuring</h3>
<pre><code class="language-javascript">const numbers = [10, 20, 30];

const [first, second, third] = numbers;

console.log(first, second, third);
</code></pre>
<p>This is shorter and easier to read.</p>
<hr />
<h3>Skipping Values</h3>
<p>You can skip elements if needed:</p>
<pre><code class="language-javascript">const numbers = [10, 20, 30];

const [first, , third] = numbers;
</code></pre>
<hr />
<h2>Destructuring Objects</h2>
<h3>Without Destructuring</h3>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};

const name = user.name;
const age = user.age;
</code></pre>
<hr />
<h3>With Destructuring</h3>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};

const { name, age } = user;

console.log(name, age);
</code></pre>
<p>This removes repetition and improves clarity.</p>
<hr />
<h3>Renaming Variables</h3>
<p>You can also rename variables while destructuring:</p>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};

const { name: userName, age: userAge } = user;

console.log(userName, userAge);
</code></pre>
<hr />
<h2>Default Values</h2>
<p>Destructuring allows you to assign default values if a property does not exist.</p>
<p>Example:</p>
<pre><code class="language-javascript">const user = {
  name: "Dipan"
};

const { name, age = 18 } = user;

console.log(name, age);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Dipan 18
</code></pre>
<p>This ensures your code does not break when a value is missing.</p>
<hr />
<h2>Comparing Before and After</h2>
<h3>Without Destructuring</h3>
<pre><code class="language-javascript">function printUser(user) {
  console.log(user.name);
  console.log(user.age);
}
</code></pre>
<hr />
<h3>With Destructuring</h3>
<pre><code class="language-javascript">function printUser({ name, age }) {
  console.log(name);
  console.log(age);
}
</code></pre>
<p>The destructured version is cleaner and avoids repetitive property access.</p>
<hr />
<h2>Benefits of Destructuring</h2>
<p>Destructuring provides several advantages:</p>
<h3>Reduces Repetitive Code</h3>
<p>You do not need to repeatedly write object or array references.</p>
<hr />
<h3>Improves Readability</h3>
<p>The code becomes more concise and easier to understand.</p>
<hr />
<h3>Makes Function Parameters Cleaner</h3>
<p>You can directly extract required values from objects passed into functions.</p>
<hr />
<h3>Handles Missing Values Gracefully</h3>
<p>Default values help prevent errors when data is incomplete.</p>
<hr />
<h2>Practical Example</h2>
<p>Destructuring is commonly used when working with APIs.</p>
<pre><code class="language-javascript">const response = {
  user: {
    name: "Dipan",
    age: 21
  }
};

const {
  user: { name, age }
} = response;

console.log(name, age);
</code></pre>
<p>This allows you to extract deeply nested values easily.</p>
<hr />
<h2>Conclusion</h2>
<p>Destructuring is a powerful feature in JavaScript that simplifies working with arrays and objects.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Destructuring allows you to extract values into variables</p>
</li>
<li><p>It works with both arrays and objects</p>
</li>
<li><p>Default values can be assigned to avoid undefined errors</p>
</li>
<li><p>It reduces repetitive code and improves readability</p>
</li>
</ul>
<p>By using destructuring, you can write cleaner, more maintainable JavaScript and make your code easier to understand.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Promises in JavaScript]]></title><description><![CDATA[As JavaScript applications grew more complex, developers needed a better way to handle asynchronous operations. Earlier, callbacks were widely used for this purpose, but they often led to deeply neste]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-promises-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-promises-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[promises]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:21:46 GMT</pubDate><content:encoded><![CDATA[<p>As JavaScript applications grew more complex, developers needed a better way to handle asynchronous operations. Earlier, callbacks were widely used for this purpose, but they often led to deeply nested code that was difficult to read and maintain.</p>
<p>To improve this situation, JavaScript introduced <strong>Promises</strong>. Promises provide a structured and readable way to manage asynchronous operations and handle their results.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What problem promises solve</p>
</li>
<li><p>Promise states (pending, fulfilled, rejected)</p>
</li>
<li><p>The basic promise lifecycle</p>
</li>
<li><p>Handling success and failure</p>
</li>
<li><p>The concept of promise chaining</p>
</li>
</ul>
<hr />
<h2>The Problem with Callbacks</h2>
<p>Before promises, asynchronous code was often written using callbacks.</p>
<p>Example:</p>
<pre><code class="language-javascript">getUser(function(user) {
  getOrders(user.id, function(orders) {
    getOrderDetails(orders[0], function(details) {
      console.log(details);
    });
  });
});
</code></pre>
<p>This structure creates deeply nested code that becomes harder to understand and maintain as the application grows.</p>
<p>This situation is sometimes referred to as <strong>callback nesting</strong>.</p>
<p>Promises were introduced to make asynchronous code <strong>cleaner and easier to manage</strong>.</p>
<hr />
<h2>What Is a Promise?</h2>
<p>A <strong>promise</strong> represents a value that may be available <strong>now, later, or never</strong>.</p>
<p>In other words, a promise is an object that represents the <strong>future result of an asynchronous operation</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  const success = true;

  if (success) {
    resolve("Operation successful");
  } else {
    reject("Operation failed");
  }
});
</code></pre>
<p>The promise will eventually produce either a successful result or an error.</p>
<hr />
<h2>Promise States</h2>
<p>A promise can exist in one of three states.</p>
<h3>Pending</h3>
<p>The promise has been created but the result is not yet available.</p>
<pre><code class="language-plaintext">Pending → Operation still in progress
</code></pre>
<hr />
<h3>Fulfilled</h3>
<p>The operation completed successfully and produced a value.</p>
<pre><code class="language-plaintext">Fulfilled → Promise resolved successfully
</code></pre>
<hr />
<h3>Rejected</h3>
<p>The operation failed and returned an error.</p>
<pre><code class="language-plaintext">Rejected → Promise failed
</code></pre>
<p>Visual representation:</p>
<pre><code class="language-plaintext">Pending
   ↓
Fulfilled  (success)
   or
Rejected   (error)
</code></pre>
<p>Once a promise is fulfilled or rejected, its state cannot change.</p>
<hr />
<h2>Basic Promise Lifecycle</h2>
<p>Let us look at a simple example.</p>
<pre><code class="language-javascript">const myPromise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("Data received");
  }, 2000);
});
</code></pre>
<p>Here:</p>
<ol>
<li><p>A promise is created.</p>
</li>
<li><p>It starts in the <strong>pending state</strong>.</p>
</li>
<li><p>After 2 seconds, <code>resolve()</code> is called.</p>
</li>
<li><p>The promise becomes <strong>fulfilled</strong>.</p>
</li>
</ol>
<hr />
<h2>Handling Success and Failure</h2>
<p>Promises provide methods to handle both success and failure.</p>
<h3>Handling Success with <code>.then()</code></h3>
<pre><code class="language-javascript">myPromise.then(result =&gt; {
  console.log(result);
});
</code></pre>
<hr />
<h3>Handling Errors with <code>.catch()</code></h3>
<pre><code class="language-javascript">myPromise
  .then(result =&gt; {
    console.log(result);
  })
  .catch(error =&gt; {
    console.error(error);
  });
</code></pre>
<p>This structure separates <strong>success handling</strong> from <strong>error handling</strong>, making code easier to understand.</p>
<hr />
<h2>Promise Chaining</h2>
<p>One of the most powerful features of promises is <strong>chaining</strong>.</p>
<p>Promise chaining allows multiple asynchronous operations to run sequentially.</p>
<p>Example:</p>
<pre><code class="language-javascript">fetchUser()
  .then(user =&gt; {
    return fetchOrders(user.id);
  })
  .then(orders =&gt; {
    return fetchOrderDetails(orders[0]);
  })
  .then(details =&gt; {
    console.log(details);
  })
  .catch(error =&gt; {
    console.error(error);
  });
</code></pre>
<p>Instead of nesting callbacks, each step returns a promise that can be handled in the next <code>.then()</code>.</p>
<p>This keeps the code <strong>structured and readable</strong>.</p>
<hr />
<h2>Promises vs Callbacks</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Callbacks</th>
<th>Promises</th>
</tr>
</thead>
<tbody><tr>
<td>Code structure</td>
<td>Often nested</td>
<td>Linear and readable</td>
</tr>
<tr>
<td>Error handling</td>
<td>Harder to manage</td>
<td>Centralized with <code>.catch()</code></td>
</tr>
<tr>
<td>Readability</td>
<td>Decreases with complexity</td>
<td>Easier to follow</td>
</tr>
<tr>
<td>Chaining operations</td>
<td>Difficult</td>
<td>Built-in support</td>
</tr>
</tbody></table>
<p>Promises significantly improve the readability and maintainability of asynchronous code.</p>
<hr />
<h2>Real-World Example</h2>
<p>Fetching data from an API is a common use case for promises.</p>
<pre><code class="language-javascript">fetch("https://api.example.com/data")
  .then(response =&gt; response.json())
  .then(data =&gt; {
    console.log(data);
  })
  .catch(error =&gt; {
    console.error("Error:", error);
  });
</code></pre>
<p>Here:</p>
<ul>
<li><p>The request returns a promise</p>
</li>
<li><p><code>.then()</code> handles the successful response</p>
</li>
<li><p><code>.catch()</code> handles any errors</p>
</li>
</ul>
<hr />
<h2>Conclusion</h2>
<p>Promises are a fundamental part of modern JavaScript and provide a better way to handle asynchronous operations compared to traditional callbacks.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Promises represent the <strong>future result of an asynchronous operation</strong></p>
</li>
<li><p>They have three states: <strong>pending, fulfilled, and rejected</strong></p>
</li>
<li><p><code>.then()</code> handles successful results</p>
</li>
<li><p><code>.catch()</code> handles errors</p>
</li>
<li><p>Promise chaining allows multiple asynchronous tasks to run in sequence</p>
</li>
</ul>
<p>Understanding promises is an important step toward mastering asynchronous JavaScript and working effectively with modern APIs and applications.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Synchronous and Asynchronous JavaScript]]></title><description><![CDATA[When learning JavaScript, one of the most important concepts to understand is how code executes. JavaScript can run code synchronously or asynchronously, and understanding the difference between these]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-synchronous-and-asynchronous-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-synchronous-and-asynchronous-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[asynchronous JavaScript]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:01:16 GMT</pubDate><content:encoded><![CDATA[<p>When learning JavaScript, one of the most important concepts to understand is how code executes. JavaScript can run code <strong>synchronously</strong> or <strong>asynchronously</strong>, and understanding the difference between these two execution styles helps explain how JavaScript handles tasks like API requests, timers, and user interactions.</p>
<p>In this article, we will explore:</p>
<ul>
<li><p>What synchronous code means</p>
</li>
<li><p>What asynchronous code means</p>
</li>
<li><p>Why JavaScript needs asynchronous behavior</p>
</li>
<li><p>Examples such as API calls and timers</p>
</li>
<li><p>Problems that occur with blocking code</p>
</li>
</ul>
<hr />
<h2>What Is Synchronous Code?</h2>
<p><strong>Synchronous code</strong> runs <strong>step by step</strong>, in the exact order it appears in the program.</p>
<p>Each line of code must finish executing before the next line begins.</p>
<p>Example:</p>
<pre><code class="language-javascript">console.log("Step 1");
console.log("Step 2");
console.log("Step 3");
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Step 1
Step 2
Step 3
</code></pre>
<p>Execution happens in a strict sequence:</p>
<pre><code class="language-plaintext">Step 1 → Step 2 → Step 3
</code></pre>
<p>JavaScript reads the program from top to bottom and executes each instruction one at a time.</p>
<hr />
<h2>Step-by-Step Execution Example</h2>
<p>Consider the following example:</p>
<pre><code class="language-javascript">function task1() {
  console.log("Task 1 completed");
}

function task2() {
  console.log("Task 2 completed");
}

task1();
task2();
</code></pre>
<p>Execution order:</p>
<pre><code class="language-plaintext">task1() runs
↓
"Task 1 completed" printed
↓
task2() runs
↓
"Task 2 completed" printed
</code></pre>
<p>Nothing happens simultaneously. Each task waits for the previous one to finish.</p>
<hr />
<h2>What Is Asynchronous Code?</h2>
<p><strong>Asynchronous code</strong> allows JavaScript to start a task and continue executing other code without waiting for that task to finish.</p>
<p>Example using <code>setTimeout</code>:</p>
<pre><code class="language-javascript">console.log("Start");

setTimeout(() =&gt; {
  console.log("Timer finished");
}, 2000);

console.log("End");
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Start
End
Timer finished
</code></pre>
<p>Execution order visually:</p>
<pre><code class="language-plaintext">Start
↓
Timer scheduled
↓
End
↓
(after 2 seconds)
Timer finished
</code></pre>
<p>Even though the timer appears earlier in the code, JavaScript does not wait for it to finish.</p>
<hr />
<h2>Why JavaScript Needs Asynchronous Behavior</h2>
<p>JavaScript is commonly used in environments where waiting for tasks can take time. For example:</p>
<ul>
<li><p>Fetching data from an API</p>
</li>
<li><p>Reading files</p>
</li>
<li><p>Waiting for user input</p>
</li>
<li><p>Running timers</p>
</li>
</ul>
<p>If JavaScript waited for each of these operations to complete before continuing, the application would become slow and unresponsive.</p>
<p>Asynchronous behavior allows JavaScript to <strong>continue running other code while waiting for results</strong>.</p>
<hr />
<h2>Everyday Example: Waiting for Data</h2>
<p>Imagine ordering food at a restaurant.</p>
<h3>Synchronous scenario</h3>
<pre><code class="language-plaintext">Order food
Wait for food to cook
Eat
Leave
</code></pre>
<p>You cannot do anything else while waiting.</p>
<h3>Asynchronous scenario</h3>
<pre><code class="language-plaintext">Order food
Talk with friends
Food arrives later
Eat
</code></pre>
<p>While waiting for the food, you can continue doing other activities.</p>
<p>JavaScript works in a similar way when handling asynchronous operations.</p>
<hr />
<h2>Example: API Call</h2>
<p>Fetching data from a server is a common asynchronous task.</p>
<pre><code class="language-javascript">console.log("Requesting data...");

fetch("https://api.example.com/data")
  .then(response =&gt; response.json())
  .then(data =&gt; console.log("Data received:", data));

console.log("Other code running...");
</code></pre>
<p>Output flow:</p>
<pre><code class="language-plaintext">Requesting data...
Other code running...
Data received: ...
</code></pre>
<p>The program does not stop while waiting for the API response.</p>
<hr />
<h2>Blocking vs Non-Blocking Code</h2>
<h3>Blocking Code (Synchronous)</h3>
<p>Blocking code prevents the program from continuing until the current task finishes.</p>
<p>Example:</p>
<pre><code class="language-plaintext">Start task
Wait until task finishes
Continue program
</code></pre>
<p>If the task takes a long time, the program becomes unresponsive.</p>
<hr />
<h3>Non-Blocking Code (Asynchronous)</h3>
<p>Non-blocking code allows the program to continue running while waiting for tasks to complete.</p>
<p>Example:</p>
<pre><code class="language-plaintext">Start task
Continue program
Task finishes later
Handle result
</code></pre>
<p>This behavior keeps applications responsive.</p>
<hr />
<h2>Problems with Blocking Code</h2>
<p>Blocking operations can cause several issues:</p>
<h3>Slow Applications</h3>
<p>If the program waits for long tasks, everything else stops.</p>
<hr />
<h3>Poor User Experience</h3>
<p>In web applications, blocking code can freeze the interface, making the page appear unresponsive.</p>
<hr />
<h3>Reduced Performance</h3>
<p>Programs cannot perform multiple operations efficiently when blocked.</p>
<p>Asynchronous programming helps avoid these problems.</p>
<hr />
<h2>Conclusion</h2>
<p>Understanding synchronous and asynchronous behavior is essential for working with JavaScript effectively.</p>
<p>Key points to remember:</p>
<ul>
<li><p><strong>Synchronous code</strong> runs step by step in order</p>
</li>
<li><p><strong>Asynchronous code</strong> allows tasks to run without blocking the program</p>
</li>
<li><p>JavaScript uses asynchronous behavior for tasks like API requests and timers</p>
</li>
<li><p>Blocking code can slow down applications and harm user experience</p>
</li>
<li><p>Asynchronous programming keeps applications responsive and efficient</p>
</li>
</ul>
<p>As you continue learning JavaScript, concepts such as <strong>callbacks, promises, and async/await</strong> will help you manage asynchronous operations more effectively.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Async/Await in JavaScript]]></title><description><![CDATA[As JavaScript applications became more complex, handling asynchronous operations using callbacks started to become difficult to manage. This led to deeply nested code structures, often referred to as ]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-async-await-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-async-await-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Javascript Promises]]></category><category><![CDATA[asynchronous JavaScript]]></category><category><![CDATA[async/await]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 17:38:30 GMT</pubDate><content:encoded><![CDATA[<p>As JavaScript applications became more complex, handling asynchronous operations using callbacks started to become difficult to manage. This led to deeply nested code structures, often referred to as <strong>callback hell</strong>.</p>
<p>Promises improved this situation, but chaining multiple <code>.then()</code> calls could still make code harder to read. To simplify asynchronous programming further, JavaScript introduced <strong>async/await</strong>.</p>
<p>Async/await provides a cleaner and more readable way to write asynchronous code while still using the power of promises.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>Why async/await was introduced</p>
</li>
<li><p>How async functions work</p>
</li>
<li><p>The concept of the <code>await</code> keyword</p>
</li>
<li><p>Error handling with async code</p>
</li>
<li><p>Comparison with promises</p>
</li>
</ul>
<hr />
<h2>Why Async/Await Was Introduced</h2>
<p>Before async/await, asynchronous code was commonly written using <strong>callbacks</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">getUser(function(user) {
  getOrders(user.id, function(orders) {
    getOrderDetails(orders[0], function(details) {
      console.log(details);
    });
  });
});
</code></pre>
<p>This nested structure becomes difficult to read and maintain.</p>
<p>Promises improved this by allowing chaining:</p>
<pre><code class="language-javascript">getUser()
  .then(user =&gt; getOrders(user.id))
  .then(orders =&gt; getOrderDetails(orders[0]))
  .then(details =&gt; console.log(details))
  .catch(error =&gt; console.error(error));
</code></pre>
<p>While promises are better, async/await was introduced to make asynchronous code <strong>look and behave more like synchronous code</strong>, improving readability.</p>
<hr />
<h2>Async/Await as Syntactic Sugar</h2>
<p>Async/await is often described as <strong>syntactic sugar over promises</strong>.</p>
<p>This means:</p>
<ul>
<li><p>It does not replace promises</p>
</li>
<li><p>It simply provides a cleaner syntax for working with them</p>
</li>
</ul>
<p>Behind the scenes, async functions still return promises.</p>
<hr />
<h2>How Async Functions Work</h2>
<p>An <strong>async function</strong> is declared using the <code>async</code> keyword.</p>
<p>Example:</p>
<pre><code class="language-javascript">async function greet() {
  return "Hello";
}
</code></pre>
<p>Even though the function returns a string, JavaScript automatically wraps it in a promise.</p>
<p>Example:</p>
<pre><code class="language-javascript">async function greet() {
  return "Hello";
}

greet().then(result =&gt; console.log(result));
</code></pre>
<p>Output:</p>
<pre><code class="language-id=&quot;as03&quot;">Hello
</code></pre>
<hr />
<h2>The <code>await</code> Keyword</h2>
<p>The <code>await</code> keyword is used <strong>inside async functions</strong> to pause execution until a promise resolves.</p>
<p>Example:</p>
<pre><code class="language-javascript">function fetchData() {
  return new Promise(resolve =&gt; {
    setTimeout(() =&gt; {
      resolve("Data received");
    }, 2000);
  });
}

async function getData() {
  const result = await fetchData();
  console.log(result);
}

getData();
</code></pre>
<p>Explanation:</p>
<ol>
<li><p><code>fetchData()</code> returns a promise</p>
</li>
<li><p><code>await</code> pauses the function until the promise resolves</p>
</li>
<li><p>The resolved value is stored in <code>result</code></p>
</li>
</ol>
<p>This makes asynchronous code look much simpler and easier to understand.</p>
<hr />
<h2>Improving Readability with Async/Await</h2>
<p>Let us compare promise-based code with async/await.</p>
<h3>Using Promises</h3>
<pre><code class="language-javascript">function fetchUser() {
  return Promise.resolve("User data");
}

fetchUser()
  .then(data =&gt; {
    console.log(data);
  })
  .catch(error =&gt; {
    console.error(error);
  });
</code></pre>
<h3>Using Async/Await</h3>
<pre><code class="language-javascript">async function getUser() {
  try {
    const data = await fetchUser();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

getUser();
</code></pre>
<p>The async/await version is <strong>cleaner and easier to read</strong>, especially when multiple asynchronous operations are involved.</p>
<hr />
<h2>Error Handling with Async Code</h2>
<p>Error handling with async/await uses the familiar <strong>try...catch</strong> structure.</p>
<p>Example:</p>
<pre><code class="language-javascript">async function fetchData() {
  try {
    const response = await Promise.reject("Something went wrong");
    console.log(response);
  } catch (error) {
    console.log("Error:", error);
  }
}

fetchData();
</code></pre>
<p>This approach keeps error handling <strong>structured and readable</strong>.</p>
<hr />
<h2>Comparison with Promises</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Promises</th>
<th>Async/Await</th>
</tr>
</thead>
<tbody><tr>
<td>Syntax style</td>
<td><code>.then()</code> and <code>.catch()</code></td>
<td>Looks like synchronous code</td>
</tr>
<tr>
<td>Readability</td>
<td>Can become complex with chaining</td>
<td>Easier to read</td>
</tr>
<tr>
<td>Error handling</td>
<td><code>.catch()</code></td>
<td><code>try...catch</code></td>
</tr>
<tr>
<td>Underlying behavior</td>
<td>Promise-based</td>
<td>Built on top of promises</td>
</tr>
</tbody></table>
<p>Async/await improves code readability but still relies on promises internally.</p>
<hr />
<h2>Simple Real-World Example</h2>
<p>Fetching data from an API often involves asynchronous code.</p>
<p>Example:</p>
<pre><code class="language-javascript">async function loadData() {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();

  console.log(data);
}

loadData();
</code></pre>
<p>Here, <code>await</code> ensures that each step completes before moving to the next.</p>
<hr />
<h2>Conclusion</h2>
<p>Async/await is a powerful feature that simplifies asynchronous programming in JavaScript. By providing a cleaner syntax over promises, it allows developers to write code that is easier to read, maintain, and debug.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Async/await was introduced to simplify asynchronous code</p>
</li>
<li><p><code>async</code> functions always return promises</p>
</li>
<li><p><code>await</code> pauses execution until a promise resolves</p>
</li>
<li><p>Error handling works naturally with <code>try...catch</code></p>
</li>
<li><p>Async/await improves readability while still relying on promises internally</p>
</li>
</ul>
<p>Understanding async/await will help you write more maintainable JavaScript and manage asynchronous workflows more effectively.</p>
]]></content:encoded></item><item><title><![CDATA[Error Handling in JavaScript: Understanding try, catch, and finally]]></title><description><![CDATA[When writing JavaScript programs, errors are inevitable. These errors can occur due to invalid operations, unexpected inputs, or issues during runtime. Proper error handling allows developers to manag]]></description><link>https://dipan-roy-choudhury.hashnode.dev/error-handling-in-javascript-understanding-try-catch-and-finally</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/error-handling-in-javascript-understanding-try-catch-and-finally</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[trycatch]]></category><category><![CDATA[try-catch-finally]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 17:32:02 GMT</pubDate><content:encoded><![CDATA[<p>When writing JavaScript programs, errors are inevitable. These errors can occur due to invalid operations, unexpected inputs, or issues during runtime. Proper <strong>error handling</strong> allows developers to manage these situations gracefully instead of letting the application crash.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What errors are in JavaScript</p>
</li>
<li><p>Using <code>try</code> and <code>catch</code> blocks</p>
</li>
<li><p>The <code>finally</code> block</p>
</li>
<li><p>Throwing custom errors</p>
</li>
<li><p>Why error handling is important</p>
</li>
</ul>
<hr />
<h2>What Are Errors in JavaScript?</h2>
<p>An <strong>error</strong> occurs when something unexpected happens during the execution of a program.</p>
<p>Example:</p>
<pre><code class="language-javascript">const user = undefined;

console.log(user.name);
</code></pre>
<p>This will produce a runtime error:</p>
<pre><code class="language-plaintext">TypeError: Cannot read properties of undefined
</code></pre>
<p>Another example:</p>
<pre><code class="language-javascript">console.log(x);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">ReferenceError: x is not defined
</code></pre>
<p>These are called <strong>runtime errors</strong>, because they occur while the program is running.</p>
<p>Without proper handling, such errors can stop the program completely.</p>
<hr />
<h2>Handling Errors with <code>try</code> and <code>catch</code></h2>
<p>JavaScript provides the <code>try...catch</code> structure to handle errors safely.</p>
<p>Example:</p>
<pre><code class="language-javascript">try {
  const user = undefined;
  console.log(user.name);
} catch (error) {
  console.log("An error occurred:", error.message);
}
</code></pre>
<p>Explanation:</p>
<ul>
<li><p>Code inside the <code>try</code> <strong>block</strong> is executed normally.</p>
</li>
<li><p>If an error occurs, execution immediately jumps to the <code>catch</code> <strong>block</strong>.</p>
</li>
<li><p>The <code>catch</code> block receives the error object and allows you to handle it.</p>
</li>
</ul>
<p>Output:</p>
<pre><code class="language-plaintext">An error occurred: Cannot read properties of undefined
</code></pre>
<p>Instead of crashing the program, the error is handled gracefully.</p>
<hr />
<h2>Graceful Failure</h2>
<p>Error handling allows programs to <strong>fail gracefully</strong>, meaning they can recover or provide useful feedback instead of breaking entirely.</p>
<p>Example:</p>
<pre><code class="language-javascript">function divide(a, b) {
  try {
    if (b === 0) {
      throw new Error("Division by zero is not allowed");
    }
    return a / b;
  } catch (error) {
    console.log(error.message);
  }
}

divide(10, 0);
</code></pre>
<p>Here, the program detects a problem and handles it properly.</p>
<hr />
<h2>The <code>finally</code> Block</h2>
<p>The <code>finally</code> block is optional but useful. It runs <strong>regardless of whether an error occurs or not</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">try {
  console.log("Processing data...");
} catch (error) {
  console.log("An error occurred");
} finally {
  console.log("Execution completed");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Processing data...
Execution completed
</code></pre>
<p><code>finally</code> is often used for <strong>cleanup tasks</strong>, such as:</p>
<ul>
<li><p>Closing files</p>
</li>
<li><p>Releasing resources</p>
</li>
<li><p>Ending database connections</p>
</li>
</ul>
<hr />
<h2>Throwing Custom Errors</h2>
<p>Developers can also create their own errors using the <code>throw</code> statement.</p>
<p>Example:</p>
<pre><code class="language-javascript">function checkAge(age) {
  if (age &lt; 18) {
    throw new Error("Access denied: Age must be 18 or older");
  }
  return "Access granted";
}

try {
  console.log(checkAge(16));
} catch (error) {
  console.log(error.message);
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Access denied: Age must be 18 or older
</code></pre>
<p>Custom errors help developers enforce rules and validate input effectively.</p>
<hr />
<h2>Why Error Handling Matters</h2>
<p>Proper error handling is essential for building reliable applications.</p>
<h3>Prevents Application Crashes</h3>
<p>Without error handling, one small issue can stop the entire program.</p>
<hr />
<h3>Improves Debugging</h3>
<p>Error messages help developers quickly identify what went wrong and where the issue occurred.</p>
<hr />
<h3>Enhances User Experience</h3>
<p>Instead of showing technical error messages, applications can display user-friendly messages.</p>
<p>Example:</p>
<pre><code class="language-plaintext">Unable to load data. Please try again later.
</code></pre>
<hr />
<h3>Makes Code More Robust</h3>
<p>Programs that anticipate and handle errors are more stable and easier to maintain.</p>
<hr />
<h2>Conclusion</h2>
<p>Errors are a natural part of programming, but proper error handling allows developers to manage them effectively.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Errors occur when something unexpected happens during program execution</p>
</li>
<li><p><code>try</code> and <code>catch</code> allow you to safely handle runtime errors</p>
</li>
<li><p><code>finally</code> runs regardless of whether an error occurs</p>
</li>
<li><p>Custom errors can be created using <code>throw</code></p>
</li>
<li><p>Proper error handling improves debugging, stability, and user experience</p>
</li>
</ul>
<p>By incorporating error handling into your JavaScript programs, you can create applications that are more reliable, maintainable, and easier to debug.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding the Spread and Rest Operators in JavaScript]]></title><description><![CDATA[Modern JavaScript introduced several features that make code cleaner and easier to write. Two of these features are the spread operator (...) and the rest operator (...).
Although they use the same sy]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-the-spread-and-rest-operators-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-the-spread-and-rest-operators-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Spread operator]]></category><category><![CDATA[Rest operator]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 17:27:49 GMT</pubDate><content:encoded><![CDATA[<p>Modern JavaScript introduced several features that make code cleaner and easier to write. Two of these features are the <strong>spread operator (</strong><code>...</code><strong>)</strong> and the <strong>rest operator (</strong><code>...</code><strong>)</strong>.</p>
<p>Although they use the same syntax, they serve <strong>different purposes</strong> depending on how they are used.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What the spread operator does</p>
</li>
<li><p>What the rest operator does</p>
</li>
<li><p>The difference between spread and rest</p>
</li>
<li><p>Using spread with arrays and objects</p>
</li>
<li><p>Practical use cases in real-world JavaScript</p>
</li>
</ul>
<hr />
<h2>The Spread Operator</h2>
<p>The <strong>spread operator (</strong><code>...</code><strong>)</strong> is used to <strong>expand elements of an iterable (like arrays or objects)</strong> into individual values.</p>
<p>In simple terms:</p>
<p><strong>Spread = Expanding values</strong></p>
<h3>Example with Arrays</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3];

console.log(...numbers);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">1 2 3
</code></pre>
<p>The array elements are expanded into individual values.</p>
<hr />
<h3>Copying an Array</h3>
<p>Spread is often used to create a <strong>copy of an array</strong>.</p>
<pre><code class="language-javascript">const arr1 = [1, 2, 3];

const arr2 = [...arr1];

console.log(arr2);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, 3]
</code></pre>
<p>This creates a <strong>shallow copy</strong> of the array.</p>
<hr />
<h3>Merging Arrays</h3>
<p>Spread also makes it easy to combine arrays.</p>
<pre><code class="language-javascript">const arr1 = [1, 2];
const arr2 = [3, 4];

const merged = [...arr1, ...arr2];

console.log(merged);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, 3, 4]
</code></pre>
<p>This approach is cleaner than using older methods like <code>concat()</code>.</p>
<hr />
<h2>Spread Operator with Objects</h2>
<p>The spread operator can also be used with objects.</p>
<h3>Copying Objects</h3>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};

const copy = { ...user };

console.log(copy);
</code></pre>
<hr />
<h3>Merging Objects</h3>
<pre><code class="language-javascript">const user = { name: "Dipan" };
const details = { age: 21 };

const profile = { ...user, ...details };

console.log(profile);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">{ name: "Dipan", age: 21 }
</code></pre>
<hr />
<h2>The Rest Operator</h2>
<p>The <strong>rest operator (</strong><code>...</code><strong>)</strong> is used to <strong>collect multiple values into a single structure</strong>.</p>
<p>In simple terms:</p>
<p><strong>Rest = Collecting values</strong></p>
<hr />
<h3>Example with Function Parameters</h3>
<pre><code class="language-javascript">function sum(...numbers) {
  return numbers.reduce((total, num) =&gt; total + num, 0);
}

console.log(sum(1, 2, 3, 4));
</code></pre>
<p>Here:</p>
<ul>
<li>All arguments are collected into the <code>numbers</code> array.</li>
</ul>
<hr />
<h3>Rest with Array Destructuring</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4];

const [first, ...rest] = numbers;

console.log(first);
console.log(rest);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">1
[2, 3, 4]
</code></pre>
<p>The rest operator collects the remaining elements into an array.</p>
<hr />
<h2>Difference Between Spread and Rest</h2>
<p>Even though both use the <code>...</code> syntax, their behavior depends on the context.</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Spread Operator</th>
<th>Rest Operator</th>
</tr>
</thead>
<tbody><tr>
<td>Purpose</td>
<td>Expands elements</td>
<td>Collects elements</td>
</tr>
<tr>
<td>Usage</td>
<td>Arrays, objects, function calls</td>
<td>Function parameters, destructuring</td>
</tr>
<tr>
<td>Behavior</td>
<td>Breaks a structure into values</td>
<td>Groups values into a structure</td>
</tr>
</tbody></table>
<p>Example comparison:</p>
<pre><code class="language-javascript">// Spread
const arr = [1, 2, 3];
console.log(...arr);

// Rest
function example(...args) {
  console.log(args);
}
</code></pre>
<hr />
<h2>Practical Use Cases</h2>
<p>The spread and rest operators appear frequently in modern JavaScript applications.</p>
<h3>Passing Array Elements as Function Arguments</h3>
<pre><code class="language-javascript">const numbers = [5, 10, 15];

console.log(Math.max(...numbers));
</code></pre>
<hr />
<h3>Updating State in Applications</h3>
<p>Spread is often used to create updated objects without mutating the original one.</p>
<pre><code class="language-javascript">const user = {
  name: "Dipan",
  age: 21
};

const updatedUser = {
  ...user,
  age: 22
};
</code></pre>
<p>This pattern is common in modern frontend frameworks.</p>
<hr />
<h3>Handling Variable Arguments</h3>
<p>Rest parameters allow functions to accept <strong>any number of arguments</strong>.</p>
<pre><code class="language-javascript">function logItems(...items) {
  items.forEach(item =&gt; console.log(item));
}

logItems("apple", "banana", "mango");
</code></pre>
<hr />
<h2>Key Idea: Expanding vs Collecting</h2>
<p>The easiest way to remember the difference:</p>
<pre><code class="language-plaintext">Spread → Expands values
Rest → Collects values
</code></pre>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 3];

function example(a, b, c) {}

example(...numbers); // spread
</code></pre>
<pre><code class="language-javascript">function example(...numbers) {
  console.log(numbers);
}
</code></pre>
<hr />
<h2>Conclusion</h2>
<p>The spread and rest operators are powerful JavaScript features that simplify working with arrays, objects, and function parameters.</p>
<p>Key points to remember:</p>
<ul>
<li><p>The spread operator expands elements into individual values</p>
</li>
<li><p>The rest operator collects multiple values into one structure</p>
</li>
<li><p>Spread is commonly used for copying and merging arrays or objects</p>
</li>
<li><p>Rest is commonly used for handling variable function arguments</p>
</li>
<li><p>Both features improve code readability and flexibility</p>
</li>
</ul>
<p>Understanding how these operators work will help you write cleaner JavaScript and recognize common patterns used in modern applications.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding String Methods and Polyfills in JavaScript]]></title><description><![CDATA[Strings are one of the most commonly used data types in JavaScript. To work with strings efficiently, JavaScript provides many built-in string methods such as includes(), slice(), trim(), and toUpperC]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-string-methods-and-polyfills-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-string-methods-and-polyfills-in-javascript</guid><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 17:15:12 GMT</pubDate><content:encoded><![CDATA[<p>Strings are one of the most commonly used data types in JavaScript. To work with strings efficiently, JavaScript provides many <strong>built-in string methods</strong> such as <code>includes()</code>, <code>slice()</code>, <code>trim()</code>, and <code>toUpperCase()</code>.</p>
<p>However, experienced developers often go one step further — they try to understand <strong>how these methods work internally</strong>. This is where <strong>polyfills</strong> and manual implementations become important.</p>
<p>In this article, we will explore:</p>
<ul>
<li><p>What string methods are</p>
</li>
<li><p>Why developers write polyfills</p>
</li>
<li><p>Implementing simple string utilities</p>
</li>
<li><p>Common interview string problems</p>
</li>
<li><p>Why understanding built-in behavior matters</p>
</li>
</ul>
<hr />
<h2>What Are String Methods?</h2>
<p>String methods are <strong>built-in functions that allow us to manipulate and work with strings</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">const text = "JavaScript";

console.log(text.toUpperCase());
console.log(text.slice(0, 4));
console.log(text.includes("Script"));
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">JAVASCRIPT
Java
true
</code></pre>
<p>These methods help developers perform common operations such as:</p>
<ul>
<li><p>Searching text</p>
</li>
<li><p>Extracting substrings</p>
</li>
<li><p>Converting case</p>
</li>
<li><p>Replacing characters</p>
</li>
<li><p>Removing whitespace</p>
</li>
</ul>
<p>Without these built-in methods, string manipulation would be much harder.</p>
<hr />
<h2>Why Developers Write Polyfills</h2>
<p>A <strong>polyfill</strong> is a custom implementation of a built-in JavaScript feature.</p>
<p>Developers write polyfills mainly for two reasons:</p>
<h3>1. Browser Compatibility</h3>
<p>Older browsers may not support modern JavaScript features. A polyfill allows developers to recreate that functionality manually.</p>
<h3>2. Understanding the Internal Logic</h3>
<p>Writing polyfills helps developers understand <strong>how built-in methods actually work behind the scenes</strong>.</p>
<p>This is especially useful in <strong>technical interviews</strong>, where candidates may be asked to implement common methods manually.</p>
<hr />
<h2>Understanding How String Methods Work Conceptually</h2>
<p>Let us take a simple example.</p>
<h3>How <code>includes()</code> Works Conceptually</h3>
<p>When we write:</p>
<pre><code class="language-javascript">const text = "JavaScript";

text.includes("Script");
</code></pre>
<p>JavaScript internally:</p>
<ol>
<li><p>Reads the main string</p>
</li>
<li><p>Checks every position in the string</p>
</li>
<li><p>Compares characters with the search string</p>
</li>
<li><p>Returns <code>true</code> if a match is found</p>
</li>
</ol>
<p>So conceptually, it performs <strong>character-by-character comparison</strong>.</p>
<hr />
<h2>Implementing a Simple String Utility</h2>
<p>Let us implement a basic version of <code>includes()</code> to understand the logic.</p>
<pre><code class="language-javascript">function myIncludes(str, search) {
  for (let i = 0; i &lt;= str.length - search.length; i++) {
    let match = true;

    for (let j = 0; j &lt; search.length; j++) {
      if (str[i + j] !== search[j]) {
        match = false;
        break;
      }
    }

    if (match) {
      return true;
    }
  }

  return false;
}

console.log(myIncludes("JavaScript", "Script"));
</code></pre>
<p>Explanation:</p>
<ul>
<li><p>Loop through the string</p>
</li>
<li><p>Compare characters with the search term</p>
</li>
<li><p>Return <code>true</code> if all characters match</p>
</li>
<li><p>Otherwise return <code>false</code></p>
</li>
</ul>
<p>This demonstrates the <strong>core logic behind substring searching</strong>.</p>
<hr />
<h2>Another Example: Implementing <code>reverse()</code></h2>
<p>JavaScript does not have a built-in string reverse method, but it is a common interview problem.</p>
<p>Example implementation:</p>
<pre><code class="language-javascript">function reverseString(str) {
  let result = "";

  for (let i = str.length - 1; i &gt;= 0; i--) {
    result += str[i];
  }

  return result;
}

console.log(reverseString("JavaScript"));
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">tpircSavaJ
</code></pre>
<p>This shows how understanding loops and string indexing can help build utilities manually.</p>
<hr />
<h2>Common Interview String Problems</h2>
<p>String manipulation problems frequently appear in technical interviews.</p>
<p>Some common examples include:</p>
<h3>Reverse a String</h3>
<pre><code class="language-plaintext">Input: "hello"
Output: "olleh"
</code></pre>
<hr />
<h3>Check for Palindrome</h3>
<p>A palindrome reads the same forward and backward.</p>
<p>Example:</p>
<pre><code class="language-plaintext">Input: "madam"
Output: true
</code></pre>
<hr />
<h3>Count Character Frequency</h3>
<p>Example:</p>
<pre><code class="language-plaintext">Input: "hello"

Output:
h → 1
e → 1
l → 2
o → 1
</code></pre>
<hr />
<h3>Remove Duplicate Characters</h3>
<p>Example:</p>
<pre><code class="language-plaintext">Input: "programming"
Output: "progamin"
</code></pre>
<p>These problems test your understanding of <strong>loops, conditions, and string traversal</strong>.</p>
<hr />
<h2>Why Understanding Built-in Behavior Is Important</h2>
<p>Most developers simply use built-in methods without thinking about how they work. While this is fine for everyday coding, deeper understanding provides several benefits:</p>
<h3>Stronger Problem-Solving Skills</h3>
<p>Knowing how string operations work internally helps you design algorithms more effectively.</p>
<h3>Better Interview Performance</h3>
<p>Many technical interviews ask candidates to <strong>implement common methods manually</strong>.</p>
<h3>Deeper Understanding of JavaScript</h3>
<p>Understanding internal behavior improves your grasp of <strong>performance, edge cases, and algorithm design</strong>.</p>
<hr />
<h2>Conclusion</h2>
<p>String methods are essential tools in JavaScript, helping developers manipulate and process text efficiently. However, understanding the <strong>logic behind these methods</strong> is equally important.</p>
<p>Key takeaways:</p>
<ul>
<li><p>String methods simplify common text operations</p>
</li>
<li><p>Polyfills recreate built-in behavior manually</p>
</li>
<li><p>Implementing utilities improves problem-solving skills</p>
</li>
<li><p>Many interview questions focus on string manipulation</p>
</li>
<li><p>Understanding internal logic makes you a stronger developer</p>
</li>
</ul>
<p>By practicing simple implementations and thinking about how built-in functions work internally, you can develop a deeper understanding of JavaScript and become more confident in solving programming challenges.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding the new Keyword in JavaScript]]></title><description><![CDATA[In JavaScript, objects can be created in many ways. One of the most important and commonly used approaches involves the new keyword.
To truly understand how JavaScript creates objects, it is essential]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-the-new-keyword-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-the-new-keyword-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[new keyword]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 17:11:11 GMT</pubDate><content:encoded><![CDATA[<p>In JavaScript, objects can be created in many ways. One of the most important and commonly used approaches involves the <code>new</code> <strong>keyword</strong>.</p>
<p>To truly understand how JavaScript creates objects, it is essential to understand how <code>new</code> works internally and how it connects with <strong>constructor functions and prototypes</strong>.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What the <code>new</code> keyword does</p>
</li>
<li><p>Constructor functions</p>
</li>
<li><p>The object creation process step by step</p>
</li>
<li><p>How <code>new</code> links prototypes</p>
</li>
<li><p>Instances created from constructors</p>
</li>
</ul>
<hr />
<h2>What Does the <code>new</code> Keyword Do?</h2>
<p>The <code>new</code> keyword is used to create a new object from a <strong>constructor function</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

const user = new Person("Dipan");
</code></pre>
<p>Here, <code>new Person("Dipan")</code> creates a new object and assigns the value <code>"Dipan"</code> to its <code>name</code> property.</p>
<hr />
<h2>Constructor Functions</h2>
<p>A <strong>constructor function</strong> is a regular function used to create multiple objects with similar structure.</p>
<p>By convention, constructor function names start with a capital letter.</p>
<p>Example:</p>
<pre><code class="language-javascript">function Car(brand, model) {
  this.brand = brand;
  this.model = model;
}

const car1 = new Car("Toyota", "Corolla");
const car2 = new Car("Honda", "Civic");
</code></pre>
<p>Each time we use <code>new</code>, a <strong>new object instance</strong> is created.</p>
<hr />
<h2>Object Creation Process (Step by Step)</h2>
<p>When you use the <code>new</code> keyword, JavaScript performs several steps internally.</p>
<p>Let us break it down:</p>
<pre><code class="language-javascript">const user = new Person("Dipan");
</code></pre>
<h3>Step 1: Create an Empty Object</h3>
<p>JavaScript creates a new empty object:</p>
<pre><code class="language-id=&quot;step002&quot;">{}
</code></pre>
<hr />
<h3>Step 2: Link the Object to the Prototype</h3>
<p>The new object is linked to the constructor’s prototype:</p>
<pre><code class="language-id=&quot;step003&quot;">object.__proto__ = Person.prototype
</code></pre>
<p>This allows the object to access shared methods.</p>
<hr />
<h3>Step 3: Bind <code>this</code> to the New Object</h3>
<p>Inside the constructor function, <code>this</code> now refers to the newly created object.</p>
<pre><code class="language-javascript">this.name = name;
</code></pre>
<hr />
<h3>Step 4: Execute the Constructor Function</h3>
<p>The constructor function runs and assigns values to the object.</p>
<hr />
<h3>Step 5: Return the Object</h3>
<p>Finally, the newly created object is returned.</p>
<hr />
<h2>How <code>new</code> Links Prototypes</h2>
<p>Every constructor function has a <strong>prototype object</strong>.</p>
<p>When an object is created using <code>new</code>, it gets access to that prototype.</p>
<p>Example:</p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

const user = new Person("Dipan");

user.sayHello();
</code></pre>
<p>Explanation:</p>
<ul>
<li><p><code>sayHello</code> is not inside the object itself</p>
</li>
<li><p>It exists on <code>Person.prototype</code></p>
</li>
<li><p>The object can still access it because of the prototype link</p>
</li>
</ul>
<hr />
<h2>Instances Created from Constructors</h2>
<p>Objects created using a constructor are called <strong>instances</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function Animal(type) {
  this.type = type;
}

const dog = new Animal("Dog");
const cat = new Animal("Cat");
</code></pre>
<p>Here:</p>
<ul>
<li><code>dog</code> and <code>cat</code> are <strong>instances of</strong> <code>Animal</code></li>
</ul>
<p>You can verify this using <code>instanceof</code>:</p>
<pre><code class="language-javascript">console.log(dog instanceof Animal); // true
</code></pre>
<p>Each instance:</p>
<ul>
<li><p>Has its own properties</p>
</li>
<li><p>Shares methods through the prototype</p>
</li>
</ul>
<hr />
<h2>Relationship Between Constructor and Object</h2>
<p>Let us summarize the relationship:</p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

const user = new Person("Dipan");
</code></pre>
<ul>
<li><p><code>Person</code> → constructor function</p>
</li>
<li><p><code>user</code> → object instance</p>
</li>
<li><p><code>user.__proto__</code> → <code>Person.prototype</code></p>
</li>
</ul>
<p>This connection allows multiple objects to share behavior efficiently.</p>
<hr />
<h2>Conclusion</h2>
<p>The <code>new</code> keyword plays a crucial role in JavaScript object creation. It works together with constructor functions and prototypes to create structured and reusable objects.</p>
<p>Key takeaways:</p>
<ul>
<li><p><code>new</code> creates a new object from a constructor function</p>
</li>
<li><p>It sets up the prototype chain automatically</p>
</li>
<li><p>It binds <code>this</code> to the new object</p>
</li>
<li><p>Constructor functions help create multiple similar objects</p>
</li>
<li><p>Instances share methods through prototypes</p>
</li>
</ul>
<p>Understanding how <code>new</code> works internally gives you deeper insight into JavaScript’s object system and prepares you for advanced concepts like classes and inheritance.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Callback Functions in JavaScript]]></title><description><![CDATA[JavaScript is a language where functions are treated as values. This means functions can be stored in variables, passed to other functions, and even returned from functions. Because of this flexibilit]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-callback-functions-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-callback-functions-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[callback functions]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:57:24 GMT</pubDate><content:encoded><![CDATA[<p>JavaScript is a language where <strong>functions are treated as values</strong>. This means functions can be stored in variables, passed to other functions, and even returned from functions. Because of this flexibility, JavaScript developers often use something called <strong>callback functions</strong>.</p>
<p>Callback functions are especially important in <strong>asynchronous programming</strong>, which is very common in modern JavaScript applications.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What a callback function is</p>
</li>
<li><p>Why callbacks are used in asynchronous programming</p>
</li>
<li><p>Passing functions as arguments</p>
</li>
<li><p>Common scenarios where callbacks are used</p>
</li>
<li><p>The basic problem of callback nesting</p>
</li>
</ul>
<hr />
<h2>Functions as Values in JavaScript</h2>
<p>Before understanding callbacks, it is important to know that <strong>functions in JavaScript are first-class citizens</strong>. This means they can behave like normal values.</p>
<p>Example:</p>
<pre><code class="language-javascript">const greet = function() {
  console.log("Hello!");
};

greet();
</code></pre>
<p>Here, the function is stored in a variable and then executed.</p>
<p>Functions can also be passed as arguments to other functions.</p>
<hr />
<h2>Passing Functions as Arguments</h2>
<p>A function can receive another function as a parameter.</p>
<p>Example:</p>
<pre><code class="language-javascript">function greetUser(name) {
  console.log("Hello " + name);
}

function processUserInput(callback) {
  const name = "Dipan";
  callback(name);
}

processUserInput(greetUser);
</code></pre>
<p>Explanation:</p>
<ul>
<li><p><code>greetUser</code> is a function</p>
</li>
<li><p><code>processUserInput</code> receives another function as an argument</p>
</li>
<li><p>That function is later executed inside <code>processUserInput</code></p>
</li>
</ul>
<p>This pattern is the foundation of <strong>callback functions</strong>.</p>
<hr />
<h2>What Is a Callback Function?</h2>
<p>A <strong>callback function</strong> is a function that is <strong>passed as an argument to another function and executed later</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function sayHello() {
  console.log("Hello");
}

function executeCallback(callback) {
  callback();
}

executeCallback(sayHello);
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>sayHello</code> is passed into <code>executeCallback</code></p>
</li>
<li><p><code>executeCallback</code> runs the function later</p>
</li>
<li><p>Therefore, <code>sayHello</code> is the <strong>callback function</strong></p>
</li>
</ul>
<hr />
<h2>Why Callbacks Are Used in Asynchronous Programming</h2>
<p>JavaScript often performs tasks that take time, such as:</p>
<ul>
<li><p>Fetching data from an API</p>
</li>
<li><p>Reading files</p>
</li>
<li><p>Waiting for user input</p>
</li>
<li><p>Running timers</p>
</li>
</ul>
<p>Instead of blocking the program while waiting, JavaScript uses <strong>callbacks to execute code once a task finishes</strong>.</p>
<p>Example using <code>setTimeout</code>:</p>
<pre><code class="language-javascript">setTimeout(function() {
  console.log("This message appears after 2 seconds");
}, 2000);
</code></pre>
<p>Explanation:</p>
<ul>
<li><p><code>setTimeout</code> waits for 2 seconds</p>
</li>
<li><p>The function inside it runs afterward</p>
</li>
<li><p>That function is the <strong>callback</strong></p>
</li>
</ul>
<hr />
<h2>Callback Usage in Common Scenarios</h2>
<p>Callbacks appear in many places in JavaScript.</p>
<h3>Event Handling</h3>
<pre><code class="language-javascript">button.addEventListener("click", function() {
  console.log("Button clicked");
});
</code></pre>
<p>The function runs when the event occurs.</p>
<hr />
<h3>Array Methods</h3>
<p>Many array methods use callbacks.</p>
<p>Example with <code>map</code>:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 3];

const doubled = numbers.map(function(num) {
  return num * 2;
});

console.log(doubled);
</code></pre>
<p>Here, the function passed to <code>map</code> is a callback that runs for every element.</p>
<hr />
<h3>Asynchronous Operations</h3>
<p>Callbacks are commonly used when dealing with asynchronous tasks.</p>
<p>Example:</p>
<pre><code class="language-javascript">function fetchData(callback) {
  setTimeout(function() {
    const data = "Data received";
    callback(data);
  }, 1000);
}

fetchData(function(result) {
  console.log(result);
});
</code></pre>
<p>The callback runs once the simulated data fetch completes.</p>
<hr />
<h2>The Problem of Callback Nesting</h2>
<p>While callbacks are powerful, they can sometimes lead to code that is difficult to read when many asynchronous operations depend on each other.</p>
<p>Example:</p>
<pre><code class="language-javascript">getUser(function(user) {
  getOrders(user.id, function(orders) {
    getOrderDetails(orders[0], function(details) {
      console.log(details);
    });
  });
});
</code></pre>
<p>This structure creates <strong>deeply nested callbacks</strong>, which can become difficult to maintain.</p>
<p>This issue is often referred to as <strong>"callback hell"</strong>.</p>
<p>Modern JavaScript introduces solutions like:</p>
<ul>
<li><p><strong>Promises</strong></p>
</li>
<li><p><strong>Async/Await</strong></p>
</li>
</ul>
<p>These help manage asynchronous code in a cleaner way.</p>
<hr />
<h2>Conclusion</h2>
<p>Callback functions are a fundamental concept in JavaScript. They allow functions to be passed as arguments and executed later, making them essential for both synchronous and asynchronous programming.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Functions in JavaScript can be treated as values</p>
</li>
<li><p>A callback function is passed to another function and executed later</p>
</li>
<li><p>Callbacks are widely used in asynchronous operations</p>
</li>
<li><p>They appear in event handling, array methods, and timers</p>
</li>
<li><p>Excessive callback nesting can make code harder to read</p>
</li>
</ul>
<p>Understanding callbacks is an important step toward mastering asynchronous JavaScript and preparing for more advanced concepts like Promises and Async/Await.</p>
]]></content:encoded></item><item><title><![CDATA[Template Literals in JavaScript: Writing Cleaner and More Readable String]]></title><description><![CDATA[Working with strings is very common in JavaScript. In earlier JavaScript versions, developers used string concatenation with the + operator to combine strings and variables. While this approach works,]]></description><link>https://dipan-roy-choudhury.hashnode.dev/template-literals-in-javascript-writing-cleaner-and-more-readable-string</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/template-literals-in-javascript-writing-cleaner-and-more-readable-string</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[template literals]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:50:10 GMT</pubDate><content:encoded><![CDATA[<p>Working with strings is very common in JavaScript. In earlier JavaScript versions, developers used <strong>string concatenation</strong> with the <code>+</code> operator to combine strings and variables. While this approach works, it often becomes messy and difficult to read when the string becomes longer.</p>
<p>To solve this problem, JavaScript introduced <strong>Template Literals</strong> (also called template strings). They make working with strings cleaner, more readable, and easier to manage.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>Problems with traditional string concatenation</p>
</li>
<li><p>Template literal syntax</p>
</li>
<li><p>Embedding variables in strings</p>
</li>
<li><p>Multi-line strings</p>
</li>
<li><p>Practical use cases in modern JavaScript</p>
</li>
</ul>
<hr />
<h2>Problems with Traditional String Concatenation</h2>
<p>Before template literals, developers commonly used the <code>+</code> operator to build strings.</p>
<p>Example:</p>
<pre><code class="language-javascript">const name = "Dipan";
const age = 21;

const message = "My name is " + name + " and I am " + age + " years old.";

console.log(message);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">My name is Dipan and I am 21 years old.
</code></pre>
<p>Although this works, there are several problems:</p>
<ul>
<li><p>The code becomes <strong>harder to read</strong> when many variables are involved.</p>
</li>
<li><p>Managing spaces and punctuation becomes inconvenient.</p>
</li>
<li><p>Long strings with multiple variables look cluttered.</p>
</li>
</ul>
<p>For example:</p>
<pre><code class="language-javascript">const product = "Laptop";
const price = 800;

const text = "The product " + product + " costs $" + price + " and is available in stock.";
</code></pre>
<p>As the string grows, readability decreases.</p>
<hr />
<h2>Template Literal Syntax</h2>
<p>Template literals use <strong>backticks</strong> instead of single or double quotes.</p>
<p>The backtick character looks like this:</p>
<pre><code class="language-plaintext">`
</code></pre>
<p>Example:</p>
<pre><code class="language-javascript">const message = `This is a template literal.`;
</code></pre>
<p>The real advantage of template literals comes from <strong>embedding variables directly inside the string</strong>.</p>
<hr />
<h2>Embedding Variables in Strings</h2>
<p>With template literals, variables can be inserted using <code>${}</code> syntax.</p>
<p>Example:</p>
<pre><code class="language-javascript">const name = "Dipan";
const age = 21;

const message = `My name is \({name} and I am \){age} years old.`;

console.log(message);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">My name is Dipan and I am 21 years old.
</code></pre>
<h3>Comparison with Traditional Concatenation</h3>
<p>Old approach:</p>
<pre><code class="language-javascript">const message = "My name is " + name + " and I am " + age + " years old.";
</code></pre>
<p>Template literal approach:</p>
<pre><code class="language-javascript">const message = `My name is \({name} and I am \){age} years old.`;
</code></pre>
<p>The template literal version is <strong>much cleaner and easier to read</strong>.</p>
<hr />
<h2>Multi-line Strings</h2>
<p>Another major advantage of template literals is <strong>multi-line string support</strong>.</p>
<p>Before template literals, writing multi-line strings required concatenation.</p>
<p>Old approach:</p>
<pre><code class="language-javascript">const text = "This is line one.\n" +
             "This is line two.\n" +
             "This is line three.";
</code></pre>
<p>Using template literals:</p>
<pre><code class="language-javascript">const text = `
This is line one.
This is line two.
This is line three.
`;
</code></pre>
<p>This approach is much easier to read and maintain.</p>
<hr />
<h2>Use Cases in Modern JavaScript</h2>
<p>Template literals are widely used in modern JavaScript applications.</p>
<h3>Generating Dynamic Messages</h3>
<pre><code class="language-javascript">const username = "Dipan";

console.log(`Welcome back, ${username}!`);
</code></pre>
<hr />
<h3>Building HTML Templates</h3>
<p>Template literals are often used to generate HTML dynamically.</p>
<pre><code class="language-javascript">const product = "Laptop";
const price = 800;

const html = `
&lt;div&gt;
  &lt;h2&gt;${product}&lt;/h2&gt;
  &lt;p&gt;Price: $${price}&lt;/p&gt;
&lt;/div&gt;
`;
</code></pre>
<p>This approach is common in frontend frameworks and DOM manipulation.</p>
<hr />
<h3>Logging and Debugging</h3>
<p>Template literals make debugging easier.</p>
<pre><code class="language-javascript">const userId = 42;

console.log(`Fetching data for user with ID: ${userId}`);
</code></pre>
<hr />
<h2>Why Template Literals Improve Readability</h2>
<p>Template literals improve readability because:</p>
<ul>
<li><p>Variables can be embedded directly inside strings</p>
</li>
<li><p>No need for repetitive <code>+</code> operators</p>
</li>
<li><p>Multi-line strings are supported naturally</p>
</li>
<li><p>Code structure looks closer to natural language</p>
</li>
</ul>
<p>These benefits make code easier to understand, especially in large applications.</p>
<hr />
<h2>Conclusion</h2>
<p>Template literals are a modern JavaScript feature that significantly improves the way developers work with strings.</p>
<p>Instead of relying on traditional string concatenation, template literals allow you to write cleaner and more readable code using backticks and variable interpolation.</p>
<p>Key points to remember:</p>
<ul>
<li><p>Template literals use backticks (`)</p>
</li>
<li><p>Variables are embedded using <code>${}</code></p>
</li>
<li><p>They support multi-line strings</p>
</li>
<li><p>They improve readability and maintainability</p>
</li>
</ul>
<p>As you write more JavaScript, you will find template literals extremely useful for building dynamic strings and improving code clarity.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Nested Arrays and How to Flatten Them in JavaScript]]></title><description><![CDATA[Arrays are one of the most commonly used data structures in JavaScript. As you start solving more complex problems, you will often encounter nested arrays. Understanding how they work and how to flatt]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-nested-arrays-and-how-to-flatten-them-in-javascript</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-nested-arrays-and-how-to-flatten-them-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[flatten array]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:44:01 GMT</pubDate><content:encoded><![CDATA[<p>Arrays are one of the most commonly used data structures in JavaScript. As you start solving more complex problems, you will often encounter <strong>nested arrays</strong>. Understanding how they work and how to flatten them is an important skill for writing efficient JavaScript code and solving interview problems.</p>
<p>In this article, we will cover:</p>
<ul>
<li><p>What nested arrays are</p>
</li>
<li><p>Why flattening arrays is useful</p>
</li>
<li><p>The concept of flattening arrays</p>
</li>
<li><p>Different approaches to flatten arrays</p>
</li>
<li><p>Common interview scenarios</p>
</li>
</ul>
<hr />
<h2>What Are Nested Arrays?</h2>
<p>A <strong>nested array</strong> is simply an array that contains other arrays as its elements.</p>
<p>Example:</p>
<pre><code class="language-javascript">const numbers = [1, 2, [3, 4], [5, 6]];
</code></pre>
<p>Here, the array contains two other arrays:</p>
<pre><code class="language-plaintext">[
  1,
  2,
  [3, 4],
  [5, 6]
]
</code></pre>
<p>Nested arrays can also be deeper:</p>
<pre><code class="language-javascript">const data = [1, [2, [3, [4, 5]]]];
</code></pre>
<p>This structure creates <strong>multiple levels of arrays inside arrays</strong>.</p>
<hr />
<h2>Why Flattening Arrays Is Useful</h2>
<p>Flattening means <strong>converting a nested array into a single-level array</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">const arr = [1, 2, [3, 4], [5, 6]];
</code></pre>
<p>After flattening:</p>
<pre><code class="language-javascript">[1, 2, 3, 4, 5, 6]
</code></pre>
<p>Flattening arrays is useful in many real-world situations:</p>
<ul>
<li><p>Processing data from APIs</p>
</li>
<li><p>Handling hierarchical data</p>
</li>
<li><p>Simplifying loops and transformations</p>
</li>
<li><p>Preparing data for algorithms</p>
</li>
</ul>
<p>Many coding interviews also include problems related to flattening arrays.</p>
<hr />
<h2>Concept of Flattening Arrays</h2>
<p>The idea behind flattening is straightforward.</p>
<p>Whenever we encounter an <strong>array inside another array</strong>, we extract its elements and place them into the main array.</p>
<p>Example nested array:</p>
<pre><code class="language-plaintext">[1, [2, 3], 4]
</code></pre>
<p>Step-by-step flattening:</p>
<ol>
<li><p>Start with an empty array</p>
</li>
<li><p>Read elements one by one</p>
</li>
<li><p>If the element is <strong>not an array</strong>, add it to the result</p>
</li>
<li><p>If the element <strong>is an array</strong>, take out its elements and process them</p>
</li>
</ol>
<p>Final result:</p>
<pre><code class="language-plaintext">[1, 2, 3, 4]
</code></pre>
<p>This process continues until no nested arrays remain.</p>
<hr />
<h2>Approach 1: Using the Built-in <code>flat()</code> Method</h2>
<p>JavaScript provides a built-in method called <code>flat()</code>.</p>
<pre><code class="language-javascript">const arr = [1, 2, [3, 4], [5, 6]];

const result = arr.flat();

console.log(result);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, 3, 4, 5, 6]
</code></pre>
<p>If arrays are nested deeper, you can specify the depth.</p>
<pre><code class="language-javascript">const arr = [1, [2, [3, [4]]]];

const result = arr.flat(Infinity);
</code></pre>
<p>This flattens arrays of <strong>any depth</strong>.</p>
<hr />
<h2>Approach 2: Using Recursion</h2>
<p>Recursion is a common technique used in interview questions.</p>
<pre><code class="language-javascript">function flattenArray(arr) {
  let result = [];

  for (let item of arr) {
    if (Array.isArray(item)) {
      result = result.concat(flattenArray(item));
    } else {
      result.push(item);
    }
  }

  return result;
}

const arr = [1, [2, [3, 4]], 5];

console.log(flattenArray(arr));
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, 3, 4, 5]
</code></pre>
<p>How it works:</p>
<ol>
<li><p>Loop through each element</p>
</li>
<li><p>If the element is an array, call the function again</p>
</li>
<li><p>If it is not an array, push it into the result</p>
</li>
</ol>
<p>This approach handles <strong>arrays of any depth</strong>.</p>
<hr />
<h2>Approach 3: Using <code>reduce()</code></h2>
<p>Another functional programming approach uses <code>reduce()</code>.</p>
<pre><code class="language-javascript">function flattenArray(arr) {
  return arr.reduce((acc, curr) =&gt; {
    if (Array.isArray(curr)) {
      return acc.concat(flattenArray(curr));
    }
    return acc.concat(curr);
  }, []);
}

const arr = [1, [2, [3, 4]], 5];

console.log(flattenArray(arr));
</code></pre>
<p>This approach is compact but may be slightly harder to understand for beginners.</p>
<hr />
<h2>Visual Example of Flattening</h2>
<p>Consider this nested array:</p>
<pre><code class="language-plaintext">[1, [2, 3], [4, [5, 6]]]
</code></pre>
<p>Step-by-step flattening:</p>
<pre><code class="language-plaintext">Start:
[1, [2, 3], [4, [5, 6]]]

After first level:
[1, 2, 3, 4, [5, 6]]

Final result:
[1, 2, 3, 4, 5, 6]
</code></pre>
<p>Breaking the process into steps helps understand how flattening works internally.</p>
<hr />
<h2>Common Interview Scenarios</h2>
<p>Flattening arrays appears in many interview problems.</p>
<p>Some common variations include:</p>
<p><strong>1. Flatten an array without using</strong> <code>flat()</code></p>
<p>You may be asked to implement the logic manually using recursion or loops.</p>
<p><strong>2. Flatten arrays to a specific depth</strong></p>
<p>Example:</p>
<pre><code class="language-javascript">flatten([1, [2, [3]]], 1)
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">[1, 2, [3]]
</code></pre>
<p><strong>3. Flatten arrays with mixed data types</strong></p>
<p>Example:</p>
<pre><code class="language-javascript">[1, ["a", ["b", "c"]], 2]
</code></pre>
<p>Expected output:</p>
<pre><code class="language-plaintext">[1, "a", "b", "c", 2]
</code></pre>
<p>Interviewers often use these questions to test your <strong>understanding of recursion, arrays, and problem-solving skills</strong>.</p>
<hr />
<h2>Conclusion</h2>
<p>Nested arrays are a common structure in JavaScript, especially when dealing with hierarchical or complex data. Learning how to flatten them helps simplify data processing and improves your problem-solving ability.</p>
<p>Key takeaways:</p>
<ul>
<li><p>Nested arrays contain arrays inside arrays</p>
</li>
<li><p>Flattening converts them into a single-level array</p>
</li>
<li><p>JavaScript provides the <code>flat()</code> method for easy flattening</p>
</li>
<li><p>Recursion and <code>reduce()</code> are common manual approaches</p>
</li>
<li><p>Flattening arrays frequently appears in coding interviews</p>
</li>
</ul>
<p>Understanding these concepts will make you more comfortable working with arrays and solving algorithmic problems in JavaScript.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding JavaScript Modules]]></title><description><![CDATA[When beginners start writing JavaScript, most of the code usually lives inside a single file. This approach works for very small programs, but as a project grows, the file becomes larger, harder to ma]]></description><link>https://dipan-roy-choudhury.hashnode.dev/understanding-javascript-modules</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/understanding-javascript-modules</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[modules]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 25 Mar 2026 16:38:24 GMT</pubDate><content:encoded><![CDATA[<p>When beginners start writing JavaScript, most of the code usually lives inside a single file. This approach works for very small programs, but as a project grows, the file becomes larger, harder to manage, and difficult to maintain.</p>
<p>To solve this problem, JavaScript provides <strong>modules</strong>, which allow developers to split code into multiple files and organize projects more effectively.</p>
<p>In this article, we will understand:</p>
<ul>
<li><p>Why modules are needed</p>
</li>
<li><p>How to export functions or values</p>
</li>
<li><p>How to import modules</p>
</li>
<li><p>The difference between default and named exports</p>
</li>
<li><p>The benefits of modular code</p>
</li>
</ul>
<hr />
<h2>Why Modules Are Needed</h2>
<p>Imagine building an application with hundreds or thousands of lines of code in a single file. This leads to several problems:</p>
<ul>
<li><p>Code becomes difficult to read and maintain</p>
</li>
<li><p>Different variables or functions may accidentally share the same name</p>
</li>
<li><p>Debugging becomes harder</p>
</li>
<li><p>Reusing code across files becomes complicated</p>
</li>
</ul>
<p>Modules help solve these issues by allowing developers to <strong>separate functionality into smaller, manageable files</strong>.</p>
<p>This approach improves organization and makes the codebase easier to understand.</p>
<hr />
<h2>What Is a Module?</h2>
<p>A <strong>module</strong> is simply a JavaScript file that contains code such as variables, functions, or classes that can be reused in other files.</p>
<p>Each module has its own scope, which prevents naming conflicts between variables defined in different files.</p>
<hr />
<h2>Exporting Functions or Values</h2>
<p>To use code from one file in another file, the code must first be <strong>exported</strong>.</p>
<h3>Named Export Example</h3>
<pre><code class="language-javascript">// math.js
export const add = (a, b) =&gt; a + b;

export const subtract = (a, b) =&gt; a - b;
</code></pre>
<p>In this example, two functions are exported from the <code>math.js</code> module.</p>
<hr />
<h2>Importing a Module</h2>
<p>Once functions or values are exported, they can be <strong>imported</strong> into another file.</p>
<pre><code class="language-javascript">// app.js
import { add, subtract } from "./math.js";

console.log(add(2, 3));       // 5
console.log(subtract(5, 2));  // 3
</code></pre>
<p>Here, the functions <code>add</code> and <code>subtract</code> are imported from <code>math.js</code> and used in another file.</p>
<hr />
<h2>Default Export</h2>
<p>A module can also export a <strong>single default value</strong> using the <code>default</code> keyword.</p>
<pre><code class="language-javascript">// greet.js
export default function greet(name) {
  return `Hello, ${name}!`;
}
</code></pre>
<h3>Importing a Default Export</h3>
<pre><code class="language-javascript">import greet from "./greet.js";

console.log(greet("Dipan"));
</code></pre>
<p>Unlike named exports, the imported function name does not need to match the original name when using default exports.</p>
<hr />
<h2>Default Export vs Named Export</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Named Export</th>
<th>Default Export</th>
</tr>
</thead>
<tbody><tr>
<td>Number allowed per file</td>
<td>Multiple</td>
<td>Only one</td>
</tr>
<tr>
<td>Import syntax</td>
<td><code>import { name }</code></td>
<td><code>import anyName</code></td>
</tr>
<tr>
<td>Flexibility</td>
<td>More structured for multiple utilities</td>
<td>Simpler for single functionality</td>
</tr>
</tbody></table>
<hr />
<h2>Benefits of Modular Code</h2>
<p>Using modules provides several advantages when building applications.</p>
<h3>Better Code Organization</h3>
<p>Modules allow you to separate responsibilities into different files. For example:</p>
<ul>
<li><p><code>auth.js</code> – authentication logic</p>
</li>
<li><p><code>api.js</code> – API requests</p>
</li>
<li><p><code>utils.js</code> – helper functions</p>
</li>
</ul>
<h3>Code Reusability</h3>
<p>Functions defined in one module can be reused across different parts of the application.</p>
<h3>Easier Debugging</h3>
<p>Smaller files make it easier to identify where a bug is occurring.</p>
<h3>Improved Collaboration</h3>
<p>When working in teams, different developers can work on different modules simultaneously.</p>
<hr />
<h2>Example of Organizing Code with Modules</h2>
<p>Instead of placing everything in one file:</p>
<pre><code class="language-javascript">function login() {}
function fetchData() {}
function calculateTotal() {}
</code></pre>
<p>A modular approach would separate these concerns:</p>
<pre><code class="language-plaintext">auth.js
api.js
utils.js
</code></pre>
<p>This structure keeps the project clean and scalable.</p>
<hr />
<h2>Conclusion</h2>
<p>Modules are an essential feature in modern JavaScript development. They help developers organize code, prevent conflicts, and make applications easier to maintain.</p>
<p>If you are building larger projects, adopting a modular approach from the beginning will make your codebase more structured and easier to scale in the future.</p>
<p>As a next step, you can explore how modules are used in real projects and how tools such as bundlers and frameworks rely heavily on modular code structures.</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to Object-Oriented Programming (OOP) in JavaScript]]></title><description><![CDATA[When I first started learning programming, I noticed that many real-world things can be represented in code. For example, a car has properties like color and brand, and it can perform actions like sta]]></description><link>https://dipan-roy-choudhury.hashnode.dev/oops-js</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/oops-js</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[Object Oriented Programming]]></category><category><![CDATA[js]]></category><category><![CDATA[objects-in-js]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 11 Mar 2026 07:42:42 GMT</pubDate><content:encoded><![CDATA[<p>When I first started learning programming, I noticed that many real-world things can be represented in code. For example, a car has properties like color and brand, and it can perform actions like starting or stopping.</p>
<p>This idea is exactly what <strong>Object-Oriented Programming (OOP)</strong> is about.</p>
<p>OOP helps us organize code by modeling <strong>real-world entities</strong> using objects.</p>
<p>In this article, I’ll explain:</p>
<ul>
<li><p>What Object-Oriented Programming (OOP) means</p>
</li>
<li><p>A simple real-world analogy</p>
</li>
<li><p>What a class is in JavaScript</p>
</li>
<li><p>How to create objects using classes</p>
</li>
<li><p>The constructor method</p>
</li>
<li><p>Methods inside a class</p>
</li>
<li><p>A basic idea of encapsulation</p>
</li>
</ul>
<p>Let’s start with a simple analogy.</p>
<hr />
<h1>A Simple Real-World Analogy: Blueprint → Objects</h1>
<p>Think about building cars in a factory.</p>
<p>Before any car is made, engineers design a <strong>blueprint</strong>.</p>
<p>That blueprint describes:</p>
<ul>
<li><p>what properties a car has (color, brand, speed)</p>
</li>
<li><p>what actions it can perform (start, stop, accelerate)</p>
</li>
</ul>
<p>From the same blueprint, we can create <strong>many cars</strong>.</p>
<p>For example:</p>
<ul>
<li><p>Car 1 → Red Toyota</p>
</li>
<li><p>Car 2 → Blue BMW</p>
</li>
<li><p>Car 3 → Black Tesla</p>
</li>
</ul>
<p>In programming:</p>
<ul>
<li><p><strong>Blueprint = Class</strong></p>
</li>
<li><p><strong>Actual cars = Objects</strong></p>
</li>
</ul>
<p>So a <strong>class defines the structure</strong>, and <strong>objects are instances created from that class</strong>.</p>
<hr />
<h1>What is a Class in JavaScript?</h1>
<p>A <strong>class</strong> is like a blueprint for creating objects.</p>
<p>It defines:</p>
<ul>
<li><p>properties (data)</p>
</li>
<li><p>methods (functions related to that object)</p>
</li>
</ul>
<p>Here is a simple example.</p>
<pre><code class="language-javascript">class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
</code></pre>
<p>In this code:</p>
<ul>
<li><p><code>class Person</code> → creates a class</p>
</li>
<li><p><code>constructor()</code> → runs when an object is created</p>
</li>
<li><p><code>this.name</code> and <code>this.age</code> → properties of the object</p>
</li>
</ul>
<p>But this class alone does nothing until we <strong>create objects from it</strong>.</p>
<hr />
<h1>Creating Objects Using Classes</h1>
<p>To create an object from a class, we use the <code>new</code> <strong>keyword</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const person1 = new Person("Dipan", 22);
const person2 = new Person("Rahul", 21);

console.log(person1);
console.log(person2);
</code></pre>
<p>Here we created two objects:</p>
<ul>
<li><p><code>person1</code></p>
</li>
<li><p><code>person2</code></p>
</li>
</ul>
<p>Both follow the <strong>same structure defined by the class</strong>, but they store different values.</p>
<p>This shows one of the biggest advantages of OOP:</p>
<p>👉 <strong>Code reusability</strong></p>
<p>We write the class once and create multiple objects from it.</p>
<hr />
<h1>The Constructor Method</h1>
<p>The <strong>constructor</strong> is a special method inside a class.</p>
<p>It automatically runs <strong>when a new object is created</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Car {
  constructor(brand, color) {
    this.brand = brand;
    this.color = color;
  }
}

const car1 = new Car("Toyota", "Red");
</code></pre>
<p>When we run this:</p>
<pre><code class="language-javascript">new Car("Toyota", "Red");
</code></pre>
<p>JavaScript automatically calls:</p>
<pre><code class="language-javascript">constructor("Toyota", "Red")
</code></pre>
<p>and assigns the values to the object.</p>
<p>So the constructor helps us <strong>initialize object properties</strong>.</p>
<hr />
<h1>Methods Inside a Class</h1>
<p>Classes can also contain <strong>methods</strong>, which are functions that belong to the object.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log("Hello, my name is " + this.name);
  }
}

const person1 = new Person("Dipan", 22);

person1.greet();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, my name is Dipan
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>greet()</code> is a <strong>method</strong></p>
</li>
<li><p>It can access object properties using <code>this</code></p>
</li>
</ul>
<p>Methods allow objects to <strong>perform actions</strong>.</p>
<hr />
<h1>Basic Idea of Encapsulation</h1>
<p>Encapsulation means <strong>keeping data and related functions together inside a class</strong>.</p>
<p>Instead of writing separate variables and functions everywhere, we organize them inside a class.</p>
<p>Example without OOP:</p>
<pre><code class="language-javascript">let name = "Dipan";
let age = 22;

function printDetails() {
  console.log(name + " is " + age + " years old");
}
</code></pre>
<p>With OOP:</p>
<pre><code class="language-javascript">class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  printDetails() {
    console.log(this.name + " is " + this.age + " years old");
  }
}
</code></pre>
<p>Now the <strong>data and behavior belong to the same object</strong>.</p>
<p>This makes code:</p>
<ul>
<li><p>cleaner</p>
</li>
<li><p>easier to maintain</p>
</li>
<li><p>more organized</p>
</li>
</ul>
<hr />
<h1>Assignment Example: Student Class</h1>
<p>Let’s build a simple example step by step.</p>
<p>We will:</p>
<ul>
<li><p>Create a <code>Student</code> class</p>
</li>
<li><p>Add properties <code>name</code> and <code>age</code></p>
</li>
<li><p>Add a method to print student details</p>
</li>
<li><p>Create multiple student objects</p>
</li>
</ul>
<hr />
<h2>Step 1: Create the Class</h2>
<pre><code class="language-javascript">class Student {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  printDetails() {
    console.log("Student Name: " + this.name);
    console.log("Age: " + this.age);
  }
}
</code></pre>
<hr />
<h2>Step 2: Create Student Objects</h2>
<pre><code class="language-javascript">const student1 = new Student("Dipan", 22);
const student2 = new Student("Rahul", 21);
const student3 = new Student("Ankit", 23);
</code></pre>
<hr />
<h2>Step 3: Call the Method</h2>
<pre><code class="language-javascript">student1.printDetails();
student2.printDetails();
student3.printDetails();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Student Name: Dipan
Age: 22

Student Name: Rahul
Age: 21

Student Name: Ankit
Age: 23
</code></pre>
<p>Here we created <strong>multiple student objects using the same class</strong>.</p>
<p>This shows how powerful and reusable classes are.</p>
<hr />
<h1>Why OOP is Useful</h1>
<p>Object-Oriented Programming helps us:</p>
<ul>
<li><p>Model real-world entities in code</p>
</li>
<li><p>Reuse code using classes</p>
</li>
<li><p>Organize data and behavior together</p>
</li>
<li><p>Make programs easier to maintain</p>
</li>
</ul>
<p>Many modern frameworks and applications rely heavily on OOP concepts.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Understanding "this", call(), apply(), and bind() in JavaScript]]></title><description><![CDATA[When I first encountered this in JavaScript, it was honestly confusing. Sometimes it referred to an object, sometimes it didn’t, and sometimes it behaved differently depending on how a function was ca]]></description><link>https://dipan-roy-choudhury.hashnode.dev/this-call-apply-bind-inJs</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/this-call-apply-bind-inJs</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[this keyword]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 11 Mar 2026 07:27:12 GMT</pubDate><content:encoded><![CDATA[<p>When I first encountered <code>this</code> in JavaScript, it was honestly confusing. Sometimes it referred to an object, sometimes it didn’t, and sometimes it behaved differently depending on how a function was called.</p>
<p>After spending some time understanding it, I realized there is a very simple way to think about <code>this</code>.</p>
<p>👉 <code>this</code> <strong>basically means “who is calling the function.”</strong></p>
<p>In this article, I’ll explain:</p>
<ul>
<li><p>What <code>this</code> means in JavaScript</p>
</li>
<li><p><code>this</code> inside normal functions</p>
</li>
<li><p><code>this</code> inside objects</p>
</li>
<li><p>What <code>call()</code>, <code>apply()</code>, and <code>bind()</code> do</p>
</li>
<li><p>The difference between them</p>
</li>
</ul>
<p>Let’s start with the basics.</p>
<hr />
<h1>What <code>this</code> Means in JavaScript</h1>
<p>In JavaScript, the value of <code>this</code> depends on <strong>how a function is called</strong>.</p>
<p>A simple way to understand it is:</p>
<blockquote>
<p><code>this</code> <strong>refers to the object that is calling the function.</strong></p>
</blockquote>
<p>Think of it like this:</p>
<ul>
<li><p>If an object calls a function → <code>this</code> refers to that object</p>
</li>
<li><p>If no object calls it → <code>this</code> may refer to the global object (or be <code>undefined</code> in strict mode)</p>
</li>
</ul>
<p>Let’s look at some examples.</p>
<hr />
<h1><code>this</code> Inside Normal Functions</h1>
<p>First, let’s see what happens when we use <code>this</code> inside a regular function.</p>
<pre><code class="language-javascript">function showThis() {
  console.log(this);
}

showThis();
</code></pre>
<p>Here we are calling the function directly.</p>
<p>Since <strong>no object is calling the function</strong>, <code>this</code> usually refers to the <strong>global object</strong> (in browsers it is <code>window</code>).</p>
<p>So the important idea is:</p>
<p>👉 <code>this</code> depends on <strong>how the function is called</strong>, not where it is written.</p>
<hr />
<h1><code>this</code> Inside Objects</h1>
<p>Now let’s see how <code>this</code> behaves inside an object.</p>
<pre><code class="language-javascript">const person = {
  name: "Dipan",
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

person.greet();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, my name is Dipan
</code></pre>
<p>Why does this work?</p>
<p>Because the function is being called by the <strong>person object</strong>.</p>
<p>So inside the function:</p>
<pre><code class="language-plaintext">this = person
</code></pre>
<p>Which means:</p>
<pre><code class="language-plaintext">this.name → person.name
</code></pre>
<p>That’s why we get <code>"Dipan"</code>.</p>
<p>This is one of the most common uses of <code>this</code> in JavaScript.</p>
<hr />
<h1>What <code>call()</code> Does</h1>
<p>Sometimes we want to <strong>manually decide what</strong> <code>this</code> <strong>should be</strong>.</p>
<p>That’s where <code>call()</code> comes in.</p>
<p><code>call()</code> allows us to <strong>call a function with a specific object as</strong> <code>this</code>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function greet() {
  console.log("Hello " + this.name);
}

const user = {
  name: "Dipan"
};

greet.call(user);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello Dipan
</code></pre>
<p>What happened here?</p>
<ul>
<li><p>We used <code>call()</code> to execute <code>greet</code></p>
</li>
<li><p>We passed <code>user</code> as the value of <code>this</code></p>
</li>
</ul>
<p>So inside the function:</p>
<pre><code class="language-plaintext">this = user
</code></pre>
<hr />
<h3><code>call()</code> with Arguments</h3>
<p><code>call()</code> can also pass arguments.</p>
<pre><code class="language-javascript">function introduce(age, city) {
  console.log(this.name + " is " + age + " years old and lives in " + city);
}

const person = { name: "Dipan" };

introduce.call(person, 22, "Siliguri");
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Dipan is 22 years old and lives in Siliguri
</code></pre>
<hr />
<h1>What <code>apply()</code> Does</h1>
<p><code>apply()</code> is very similar to <code>call()</code>.</p>
<p>It also lets us <strong>set the value of</strong> <code>this</code> <strong>manually</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function greet() {
  console.log("Hello " + this.name);
}

const user = { name: "Dipan" };

greet.apply(user);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello Dipan
</code></pre>
<p>So what’s the difference?</p>
<p>The difference is <strong>how arguments are passed</strong>.</p>
<p>With <code>apply()</code>, arguments are passed <strong>as an array</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function introduce(age, city) {
  console.log(this.name + " is " + age + " years old and lives in " + city);
}

const person = { name: "Dipan" };

introduce.apply(person, [22, "Siliguri"]);
</code></pre>
<p>Notice the arguments are inside an <strong>array</strong>.</p>
<hr />
<h1>What <code>bind()</code> Does</h1>
<p><code>bind()</code> is slightly different.</p>
<p>Instead of calling the function immediately, <code>bind()</code> <strong>creates a new function with a fixed</strong> <code>this</code> <strong>value</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function greet() {
  console.log("Hello " + this.name);
}

const user = { name: "Dipan" };

const greetUser = greet.bind(user);

greetUser();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello Dipan
</code></pre>
<p>Here’s what happened:</p>
<ol>
<li><p><code>bind()</code> created a <strong>new function</strong></p>
</li>
<li><p>That function permanently uses <code>user</code> as <code>this</code></p>
</li>
<li><p>We call the new function later</p>
</li>
</ol>
<p>So:</p>
<ul>
<li><p><code>call()</code> → calls immediately</p>
</li>
<li><p><code>apply()</code> → calls immediately</p>
</li>
<li><p><code>bind()</code> → returns a new function</p>
</li>
</ul>
<hr />
<h1>Difference Between <code>call</code>, <code>apply</code>, and <code>bind</code></h1>
<p>Here’s a simple comparison table.</p>
<table>
<thead>
<tr>
<th>Method</th>
<th>When it runs</th>
<th>How arguments are passed</th>
</tr>
</thead>
<tbody><tr>
<td><code>call()</code></td>
<td>Runs immediately</td>
<td>Arguments passed one by one</td>
</tr>
<tr>
<td><code>apply()</code></td>
<td>Runs immediately</td>
<td>Arguments passed as an array</td>
</tr>
<tr>
<td><code>bind()</code></td>
<td>Returns a new function</td>
<td>Arguments passed one by one</td>
</tr>
</tbody></table>
<p>Example summary:</p>
<pre><code class="language-javascript">fn.call(obj, arg1, arg2);

fn.apply(obj, [arg1, arg2]);

const newFn = fn.bind(obj);
newFn();
</code></pre>
<hr />
<h1>A Simple Way to Remember</h1>
<p>Here’s a quick mental trick I use:</p>
<ul>
<li><p><strong>call() → Call the function immediately</strong></p>
</li>
<li><p><strong>apply() → Apply arguments as an array</strong></p>
</li>
<li><p><strong>bind() → Bind the function for later use</strong></p>
</li>
</ul>
<hr />
<p>Understanding <code>this</code> becomes much easier once you remember one simple rule:</p>
<p>👉 <code>this</code> <strong>depends on who is calling the function.</strong></p>
<p>And when we want to control it ourselves, we can use:</p>
<ul>
<li><p><code>call()</code> → call function with custom <code>this</code></p>
</li>
<li><p><code>apply()</code> → same as call but arguments in an array</p>
</li>
<li><p><code>bind()</code> → create a new function with fixed <code>this</code></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding Function Declarations vs Function Expressions in JavaScript]]></title><description><![CDATA[When I first started learning JavaScript, I noticed that I was repeating the same code again and again. For example, if I wanted to add two numbers multiple times, I had to write the logic every time.]]></description><link>https://dipan-roy-choudhury.hashnode.dev/functions</link><guid isPermaLink="true">https://dipan-roy-choudhury.hashnode.dev/functions</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[js]]></category><category><![CDATA[functions in js]]></category><dc:creator><![CDATA[Dipan Roy Choudhury]]></dc:creator><pubDate>Wed, 11 Mar 2026 06:17:13 GMT</pubDate><content:encoded><![CDATA[<p>When I first started learning JavaScript, I noticed that I was repeating the same code again and again. For example, if I wanted to add two numbers multiple times, I had to write the logic every time.</p>
<p>That’s when I learned about <strong>functions</strong>.</p>
<p>Functions allow us to <strong>write a block of code once and reuse it whenever we need it</strong>. In this article, I’ll explain:</p>
<ul>
<li><p>What functions are and why we need them</p>
</li>
<li><p>Function declaration syntax</p>
</li>
<li><p>Function expression syntax</p>
</li>
<li><p>The difference between them</p>
</li>
<li><p>A simple idea of hoisting</p>
</li>
<li><p>When to use each type</p>
</li>
</ul>
<p>Let’s start with the basics.</p>
<hr />
<h1>What Are Functions?</h1>
<p>A <strong>function</strong> is simply a <strong>reusable block of code that performs a specific task</strong>.</p>
<p>Instead of writing the same logic again and again, we put it inside a function and call it whenever needed.</p>
<h3>Example without a function</h3>
<pre><code class="language-javascript">let result1 = 5 + 3;
console.log(result1);

let result2 = 10 + 7;
console.log(result2);
</code></pre>
<p>Here we are repeating the <strong>addition logic</strong>.</p>
<h3>Using a function</h3>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}

console.log(add(5, 3));
console.log(add(10, 7));
</code></pre>
<p>Now we wrote the logic <strong>once</strong>, and we can reuse it many times.</p>
<p>That’s the power of functions.</p>
<hr />
<h1>Function Declaration Syntax</h1>
<p>One way to create a function is called a <strong>function declaration</strong>.</p>
<h3>Syntax</h3>
<pre><code class="language-javascript">function functionName(parameters) {
  // code to execute
}
</code></pre>
<h3>Example</h3>
<pre><code class="language-javascript">function greet(name) {
  console.log("Hello " + name);
}

greet("Dipan");
</code></pre>
<p>Output:</p>
<pre><code class="language-javascript">Hello Dipan
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>function</code> → keyword used to create a function</p>
</li>
<li><p><code>greet</code> → function name</p>
</li>
<li><p><code>name</code> → parameter</p>
</li>
<li><p>The code inside <code>{}</code> runs when the function is called</p>
</li>
</ul>
<hr />
<h1>Function Expression Syntax</h1>
<p>Another way to create a function is called a <strong>function expression</strong>.</p>
<p>Here, we <strong>store a function inside a variable</strong>.</p>
<h3>Syntax</h3>
<pre><code class="language-javascript">const variableName = function(parameters) {
  // code
};
</code></pre>
<h3>Example</h3>
<pre><code class="language-javascript">const greet = function(name) {
  console.log("Hello " + name);
};

greet("Dipan");
</code></pre>
<p>Output:</p>
<pre><code class="language-javascript">Hello Dipan
</code></pre>
<p>Even though it looks slightly different, it works very similarly.</p>
<p>The main difference is <strong>how the function is created and stored</strong>.</p>
<hr />
<h1>Declaration vs Expression (Side by Side)</h1>
<p>Let’s compare them directly.</p>
<h3>Function Declaration</h3>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}
</code></pre>
<h3>Function Expression</h3>
<pre><code class="language-javascript">const add = function(a, b) {
  return a + b;
};
</code></pre>
<p>Key difference:</p>
<ul>
<li><p><strong>Declaration</strong> creates the function directly</p>
</li>
<li><p><strong>Expression</strong> stores the function inside a variable</p>
</li>
</ul>
<p>Both can do the same work, but they behave differently in one important case: <strong>hoisting</strong>.</p>
<hr />
<h1>The Basic Idea of Hoisting</h1>
<p>In JavaScript, some things are <strong>available before the line where they are written</strong>. This behavior is called <strong>hoisting</strong>.</p>
<p>Don’t worry about the internal mechanics. Just remember <strong>what works and what doesn’t</strong>.</p>
<h3>Function Declaration (Works before definition)</h3>
<pre><code class="language-javascript">sayHello();

function sayHello() {
  console.log("Hello!");
}
</code></pre>
<p>This works because <strong>function declarations are hoisted</strong>.</p>
<hr />
<h3>Function Expression (Does NOT work before definition)</h3>
<pre><code class="language-javascript">sayHello();

const sayHello = function() {
  console.log("Hello!");
};
</code></pre>
<p>This will give an error.</p>
<p>Why?</p>
<p>Because the variable <code>sayHello</code> exists, but the function is <strong>not assigned yet</strong>.</p>
<p>So the rule is simple:</p>
<p>✔ Function declarations can be called <strong>before they are defined</strong>  </p>
<p>❌ Function expressions cannot</p>
<hr />
<h1>When Should You Use Each?</h1>
<p>Both types are useful in different situations.</p>
<h3>Use Function Declarations when:</h3>
<ul>
<li><p>You want simple reusable functions</p>
</li>
<li><p>The function should be available anywhere in the file</p>
</li>
<li><p>You want cleaner and easier-to-read code</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-javascript">function calculateTotal(price, tax) {
  return price + tax;
}
</code></pre>
<hr />
<h3>Use Function Expressions when:</h3>
<ul>
<li><p>You want to store functions inside variables</p>
</li>
<li><p>You want to pass functions as arguments</p>
</li>
<li><p>You want better control over when the function is created</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-javascript">const multiply = function(a, b) {
  return a * b;
};
</code></pre>
<p>Function expressions are also commonly used with <strong>callbacks and modern JavaScript patterns</strong>.</p>
]]></content:encoded></item></channel></rss>