<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rajat Oberoi</title>
    <description>The latest articles on DEV Community by Rajat Oberoi (@rajatoberoi).</description>
    <link>https://dev.to/rajatoberoi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1292112%2Fefc34c75-7900-4fab-83fb-3e9aeba49819.jpg</url>
      <title>DEV Community: Rajat Oberoi</title>
      <link>https://dev.to/rajatoberoi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rajatoberoi"/>
    <language>en</language>
    <item>
      <title>JavaScript Main Concepts &lt; In Depth &gt; Part 2</title>
      <dc:creator>Rajat Oberoi</dc:creator>
      <pubDate>Sat, 22 Jun 2024 17:13:22 +0000</pubDate>
      <link>https://dev.to/rajatoberoi/javascript-main-concepts-in-depth-part-2-2mfn</link>
      <guid>https://dev.to/rajatoberoi/javascript-main-concepts-in-depth-part-2-2mfn</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/rajatoberoi/javascript-main-concepts-edg"&gt;click for Part 1&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Closures
&lt;/h2&gt;

&lt;p&gt;A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A closure gives you access to an outer function's scope from an inner function.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let b = 3;

function impureFunc(a) {
    return a + b;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to call a function in our code, JS interpreter needs to know  about the function it self and any other data from the surroundings environment that it depends on.&lt;br&gt;
Everything needs to be neatly closed up into a box before it can be fed into the machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboaaqklreqbrlvnxz94d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboaaqklreqbrlvnxz94d.png" alt="Image description" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A pure function is a function where the output is determined solely by its input values, without observable side effects. Given the same inputs, a pure function will always return the same output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Stored in call stack
function pureFunc(a, b) {
    return a + b;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stack Memory: &lt;br&gt;
A: 2&lt;br&gt;
B: 3&lt;/p&gt;

&lt;p&gt;Call Stack:&lt;/p&gt;

&lt;p&gt;pureFunc(2, 3)&lt;/p&gt;

&lt;p&gt;An impure function is a function that interacts with or modifies some state outside its own scope, which means its output can vary even with the same inputs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In below example, in order to interpreter to call this function and also know the value of this free variable, it creates a closure and store them in a place in memory from where they can be access later. That area of memory is called the Heap.&lt;/li&gt;
&lt;li&gt;Call stack memory is short lived, and heap memory can keep data indefinitely. Later memory gets freed using GC. &lt;/li&gt;
&lt;li&gt;So a closure is a combination of a function with it's outer state or lexical environment.&lt;/li&gt;
&lt;li&gt;Closure requires more memory than pure functions.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let b = 3;//free variable

function impureFunc(a) {
    return a + b;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Impure functions often rely on external state. Closures can encapsulate and manage this state within a function scope, making it possible to create stateful functions without resorting to global variables.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createCounter() {
    let count = 0; // This is the external state

    return function() {
        count += 1; // Impure function: modifies the external state
        return count;
    };
}

const counter = createCounter();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The count variable is encapsulated in the closure created by createCounter. &lt;/li&gt;
&lt;li&gt;This allows the count variable to persist between function calls, while keeping it private and preventing it from being modified directly from the outside.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Closures are often used in JavaScript to create functions with "private" variables or to maintain state across multiple function calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memory Management and Closures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In JavaScript, closures involve storing function references along with their surrounding state. This state is stored in memory, typically in the heap, as it needs to persist beyond the scope of the function execution.&lt;/li&gt;
&lt;li&gt;When a function with a closure is no longer referenced, the memory it occupies can be garbage collected (GC). However, as long as there are references to the closure, the variables in its scope will not be freed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Case of closure: Memoization&lt;/p&gt;

&lt;p&gt;The Fibonacci sequence is a classic example where memoization can significantly improve performance. The naive recursive approach has exponential time complexity due to repeated calculations of the same values.&lt;/p&gt;

&lt;p&gt;Naive Recursive Fibonacci Function(inefficient):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function findFabonacciRecursive(number) {
    if (number &amp;lt; 2) {
        return number;
    }
    return findFabonacciRecursive(number - 1) + findFabonacciRecursive(number - 2);
}

console.log(findFabonacciRecursive(10)); // 55

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this approach, the same values of fibonacci(n) are recalculated multiple times, leading to inefficiency. By memoizing the results of the function calls, we can avoid redundant calculations and improve the performance.&lt;/p&gt;

&lt;p&gt;Memoized Fibonacci Function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// Memoized Fibonacci function using a closure
function fibonacciMaster() {
    let cache = {};
    return function fib(n) {
        if (n in cache) {
            return cache[n];
        } else {
            if (n &amp;lt; 2) {
                cache[n] = n;  // Cache the base case result
                return n;
            } else {
                cache[n] = fib(n - 1) + fib(n - 2);
                return cache[n];
            }
        }
    };
}

const fasterFib = fibonacciMaster();
console.log(fasterFib(10)); // 55
console.log(fasterFib(50)); // 12586269025
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. JavaScript Let vs Var vs Const
&lt;/h2&gt;

&lt;p&gt;Using let: It has block scope. So it is not accessible outside of a block i.e. curly braces {}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function start() {
    for(let counter = 0; counter &amp;lt; 5; counter++) {
        console.log(counter);
    }
    //console.log(counter)//ReferenceError: counter is not defined
}

start();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
0&lt;br&gt;
1&lt;br&gt;
2&lt;br&gt;
3&lt;br&gt;
4&lt;/p&gt;

&lt;p&gt;Using var: It has function scope. It's scope is not limited to the block in which it is defined but is limited to the function scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function start() {
    for(var counter = 0; counter &amp;lt; 5; counter++) {
        console.log(counter);
    }
    console.log(counter)//last value of counter after the for loop ends i.e. value 5
}

start();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
0&lt;br&gt;
1&lt;br&gt;
2&lt;br&gt;
3&lt;br&gt;
4&lt;br&gt;
5&lt;/p&gt;

&lt;p&gt;Another example of var:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function start() {
    for(var counter = 0; counter &amp;lt; 5; counter++) {
        if(true) {
            var color = 'red';
        }
    }
    console.log(color)
}

start();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When we use var outside of a function, it creates a global variable and attaches that global variable window object in browser. variables declared with let (or const) do not get attached to the global object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8j8icegfg0tfqrif0kx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8j8icegfg0tfqrif0kx.png" alt="Image description" width="496" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;window object is central, suppose we are using a third party library and it has a variable with a same name and so that variable can override our variable. Hence, we should avoid adding stuff to window object.
So, Avoid using var keyword.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key Differences Between var and let:&lt;/p&gt;

&lt;p&gt;Scope:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;var is function-scoped, meaning it is accessible throughout the entire function in which it is declared.&lt;/li&gt;
&lt;li&gt;let(&amp;amp; const) is block-scoped, meaning it is only accessible within the block (enclosed by {}) where it is declared.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hoisting: Check 8. headline to understand hoisting further.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variables declared with var are hoisted to the top of their scope and initialized with undefined.&lt;/li&gt;
&lt;li&gt;Variables declared with let(&amp;amp; const) are also hoisted, but they are not initialized. Accessing them before declaration results in a ReferenceError.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example Illustrating Scope and Hoisting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function testVar() {
  console.log(varVar); // Outputs: undefined (due to hoisting)
  var varVar = 'I am var';
  console.log(varVar); // Outputs: 'I am var'
}

function testLet() {
  // console.log(letVar); // Would throw ReferenceError (temporal dead zone)
  let letVar = 'I am let';
  console.log(letVar); // Outputs: 'I am let'
}

testVar();
testLet();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Const keyword:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The const keyword in JavaScript is used to declare variables that are constant, meaning their value cannot be reassigned after they are initialized.&lt;/li&gt;
&lt;li&gt;The binding (the reference to the value) of a const variable cannot be changed, but this does not mean the value itself is immutable. For example, if the value is an object or an array, its properties or elements can still be modified.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const y = 5;
// y = 10; // TypeError: Assignment to constant variable.

const obj = { name: 'Alice' };
obj.name = 'Bob'; // This is allowed
console.log(obj.name); // Outputs: 'Bob'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Hoisting
&lt;/h2&gt;

&lt;p&gt;In JavaScript, hoisting is a concept where variable and function declarations are moved to the top of their containing scope during the compilation phase, before the code is executed. This means that regardless of where variables and functions are declared within a scope, they are treated as if they are declared at the top.&lt;/p&gt;

&lt;p&gt;Scope in JavaScript refers to the visibility and accessibility of variables, functions, and objects in particular parts of your code during runtime&lt;/p&gt;

&lt;p&gt;Variable Hoisting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When variables are declared using var, let, or const, the declaration (not the initialization) is hoisted to the top of the scope.&lt;/li&gt;
&lt;li&gt;However, only the declaration is hoisted, not the initialization. This means that variables declared with var are initialized with undefined whereas variables declared with let or const are not initialized until the actual line of code where the declaration is made.&lt;/li&gt;
&lt;li&gt;Variables declared with let or const are hoisted to the top of their block scope, but they are not initialized until their actual declaration is evaluated during runtime. This is known as the "temporal dead zone" (TDZ).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(y);  // ReferenceError: Cannot access 'y' before initialization
let y = 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Function Hoisting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function declarations are completely hoisted, including both the function name and the function body.&lt;/li&gt;
&lt;li&gt;This allows you to call a function before it is declared in the code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo();  // "Hello, I'm John Wick!"

function getName() {
    console.log("Hello, I'm John Wick!");
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Function expressions (functions assigned to variables) are not hoisted in the same way. Only the variable declaration is hoisted, not the function initialization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getName();  // Error: getName is not a function

var getName = function() {
    console.log("Hello, I'm John Wick!");
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. IIFE (Immediately Invoked Function Expression)
&lt;/h2&gt;

&lt;p&gt;An Immediately Invoked Function Expression (IIFE) is a function in JavaScript that runs as soon as it is defined. It is a common JavaScript pattern used to create a private scope and avoid polluting the global namespace.&lt;/p&gt;

&lt;p&gt;Here is the basic structure of an IIFE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function() {
    // Your code here
})();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The function is defined within parentheses () to treat it as an expression, and it is immediately invoked with another set of parentheses ().
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function() {
    console.log("This is an IIFE");
})();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why Use IIFE?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid Global Variables: IIFEs help in avoiding global variables by creating a local scope.&lt;/li&gt;
&lt;li&gt;Encapsulation: They encapsulate the code, making it self-contained.&lt;/li&gt;
&lt;li&gt;Immediate Execution: Useful for running setup code for testing on local that should not be run again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;With Parameters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function(a, b) {
    console.log(a + b);
})(5, 10);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returning Values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
let result = (function() {
    return "Hello, World!";
})();
console.log(result);  // Outputs: Hello, World!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Arrow functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
(() =&amp;gt; {
    console.log("This is an IIFE with arrow function");
})();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Q. What does this code log out?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (var counter = 0; counter &amp;lt; 3; counter++) {
    //Closure as it depends on variable outside of it's scope.
    const log = () =&amp;gt; {
        console.log(i);
    }

    setTimeout(log, 100);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
3&lt;br&gt;
3&lt;br&gt;
3&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;var has global scope. with var we are mutating over and over again.&lt;/li&gt;
&lt;li&gt;As we are using a closure, it keeps reference to counter variable in heap memory where it can be used later after timeout is achieved.&lt;/li&gt;
&lt;li&gt;The time the setTimeout callbacks (the log functions) execute, the counter variable in the outer scope has been incremented to 3. Thus, each log function logs the final value of counter, which is 3.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (var let = 0; counter &amp;lt; 3; counter++) {
    //Closure as it depends on variable outside of it's scope.
    const log = () =&amp;gt; {
        debugger;
        console.log(i);
    }

    setTimeout(log, 100);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
0&lt;br&gt;
1&lt;br&gt;
2&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let is block scope. with let we are creating a variable that is scoped to for loop. i.e. it is local to the for loop and cannot be accessed outside of it.&lt;/li&gt;
&lt;li&gt;In case of let, closure is capturing the log function with counter variable for each iteration of loop which is 0, 1 and 2.&lt;/li&gt;
&lt;li&gt;Closure and Execution Context: Because let is block-scoped, each log function captures a unique counter variable from its respective iteration of the loop. Therefore, when each log function executes after 100 milliseconds, it logs the value of counter as it existed at the time of its creation.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>node</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>JavaScript Main Concepts &lt; In Depth &gt; Part 1</title>
      <dc:creator>Rajat Oberoi</dc:creator>
      <pubDate>Tue, 18 Jun 2024 14:24:40 +0000</pubDate>
      <link>https://dev.to/rajatoberoi/javascript-main-concepts-edg</link>
      <guid>https://dev.to/rajatoberoi/javascript-main-concepts-edg</guid>
      <description>&lt;h2&gt;
  
  
  1. Event Loop, Call Stack, Callback Queue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/rajatoberoi/understanding-the-event-loop-callback-queue-and-call-stack-in-javascript-1k7c"&gt;Explained here&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2. this Keyword
&lt;/h2&gt;

&lt;p&gt;The value of this in JavaScript depends on how a function is called, not where it is defined.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If function is a method i.e. a part of object, then this references the object itself.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const video = {
    title: 'Netflix',
    play() {
        console.log(this);
    }
}

video.play() //{ title: 'Netflix', play: [Function: play] }

video.stop = function() {
    console.log(this)
}

video.stop() //{ title: 'Netflix', play: [Function: play], stop: [Function] }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If function is a Regular function --&amp;gt; this reference the global object, i.e. global object in node and window object in web.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function playVideo() {
    console.log(this);
}

// playVideo() //Global object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If function is a Constructor function. this references the new object created from this constructor.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Video(title) {
    this.title = title;
    console.log(this);
}

const newVideo = new Video('Netflix'); //Video { title: 'Netflix' }

// new keyword creates empty object {} then this will reference the new empty object.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;*&lt;em&gt;Behaviour of this keyword in Arrow Functions&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrow functions do not have their own this context. Instead, they inherit this from the surrounding (lexical) scope where they are defined.&lt;/li&gt;
&lt;li&gt;This means that the value of this inside an arrow function is the same as the value of this outside of it.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userProfile = {
    name: 'John Wick',
    designation: 'SSE',
    team: 'Bill Payments',
    getEmployeeDetails() {
        console.log(`Name: ${this.name}, Designation: ${this.designation}`);
    },
    getTeam: () =&amp;gt; {
        console.log(`Team for employee: ${this.name} is ${this.team}`);
    }
}


userProfile.getEmployeeDetails(); //Name: John Wick, Designation: SSE
userProfile.getTeam(); //Team for employee: undefined is undefined

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Arrow functions inheriting this keyword value from their surrounding(lexical) scope.

const userProfile = {
    name: 'John Wick',
    designation: 'SSE',
    team: 'Bill Payments',
    getEmployeeDetails() {
        console.log(`Name: ${this.name}, Designation: ${this.designation}`);
        let getTeam = () =&amp;gt; {
            console.log(`Team for employee: ${this.name} is ${this.team}`);
        }
        getTeam();
    },
}


userProfile.getEmployeeDetails();

//Output:
//Name: John Wick, Designation: SSE
//Team for employee: John Wick is Bill Payments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Why arrow functions are designed like this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This behavior is intentional and solves a common issue in JavaScript when working with functions, especially when passing them as callbacks or using them within methods.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As we understood before, In a regular function, this is determined at runtime based on how the function is invoked. If it’s called as a method of an object, this refers to that object. If it’s called as a standalone function, this defaults to the global object (or undefined in strict mode).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This dynamic behavior can be problematic when using functions as callbacks or nested within methods because the context (this) can change unexpectedly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of Issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userProfile = {
    name: 'John',
    showName: function() {
        console.log(this.name); // "John"

        function nestedFunction() {
            console.log(this.name); // `this` refers to the global object, not `userProfile`
        }

        nestedFunction();
    }
};

userProfile.showName();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Here, the nestedFunction loses the context of userProfile and points to the global object instead. This can be confusing and often requires using workarounds like storing this in a variable (const self = this) or using .bind().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arrow functions solve this issue by lexically binding this—meaning they capture the this value from their enclosing scope (where they are defined), rather than creating their own.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Example of Arrow Function Preserving this:&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The arrow function getTeam correctly retains the this value from the getEmployeeDetails method,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userProfile = {
    name: 'John Wick',
    designation: 'SSE',
    team: 'Bill Payments',
    getEmployeeDetails() {
        console.log(`Name: ${this.name}, Designation: ${this.designation}`);
        const getTeam = () =&amp;gt; {
            console.log(`Team: ${this.team}`);
        }
        getTeam()
    },
}


userProfile.getEmployeeDetails();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;lt; Passing this to self {Use case} &amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hotStar = {
    title: 'Sports',
    tags: ['India Vs Pakistan', 'India Vs USA', 'Ireland VS USA'],
    showTags() {
        this.tags.forEach(function (tag) {
            console.log(this.title, tag);
        })
    }
}

hotStar.showTags()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;/p&gt;

&lt;p&gt;undefined 'India Vs Pakistan'&lt;br&gt;
undefined 'India Vs USA'&lt;br&gt;
undefined 'Ireland VS USA'&lt;/p&gt;

&lt;p&gt;Reason:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When showTags is called, this refers to the hotStar object.&lt;/li&gt;
&lt;li&gt;However, inside the forEach callback function, function is a regular function and not a method and as explained above, in regular function this references global object (window object in browsers) or be undefined in strict mode.&lt;/li&gt;
&lt;li&gt;So there is no property in global object named 'title' hence undefined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To Solve such scenario:&lt;/p&gt;

&lt;p&gt;To maintain a reference to the hotStar object within the forEach callback, the showTags method saves the reference in a variable called self(most commonly variable name used is self, we can give any name to it.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hotStar = {
    title: 'Sports',
    tags: ['India Vs Pakistan', 'India Vs USA', 'Ireland VS USA'],
    showTags() {
        let self = this;
        this.tags.forEach(function (tag) {
            console.log(self.title, tag);
        })
    }
}

hotStar.showTags()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;/p&gt;

&lt;p&gt;Sports India Vs Pakistan&lt;br&gt;
Sports India Vs USA&lt;br&gt;
Sports Ireland VS USA&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Callbacks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;General Callback: Any function that is passed as an argument to another function and is executed after some kind of event or action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous Callback: A specific type of callback that is executed after an asynchronous operation completes. These are often associated with events or tasks that are scheduled to run in the future, such as I/O operations, timers, or network requests.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getDBdata(rechargeNumber, cb) {
    console.log(`Executing select query in MySQL for  ${rechargeNumber}`)
    cb(rechargeNumber);
}


function callMerchantApi(recharge_number) {
    console.log(`Calling merchant REST API for ${recharge_number}`)
}

getDBdata('1241421414', callMerchantApi) //callMerchantApi is a callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In this JavaScript code, we have two functions: getDBdata and callMerchantApi. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The getDBdata function accepts a rechargeNumber(Customer Number) and a callback function cb. Inside getDBdata, a message is logged to the console, and then the callback function cb is called with rechargeNumber as its argument. Function passed in a function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another Example&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here below setTimeout is a function for adding a delay, and after timeout/delay of 3 seconds is achieved, callback(which here is a arrow function) gets triggered and console message is printed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setTimeout(() =&amp;gt; { 
    console.log("This message is shown after 3 seconds");
}, 3000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Major Disadvantage of Callback is Nested Callbacks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Callbacks can lead to deeply nested code (callback hell), which is hard to read and maintain.&lt;/li&gt;
&lt;li&gt;To address these drawbacks, modern JavaScript offers Promises and the async/await syntax, which simplify asynchronous code and improve readability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Promises
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In JavaScript, a Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises provide a cleaner, more flexible way to work with asynchronous code compared to traditional callback functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Promise has three states:&lt;/p&gt;

&lt;p&gt;Pending: The initial state, neither fulfilled nor rejected.&lt;br&gt;
Fulfilled: The operation completed successfully.&lt;br&gt;
Rejected: The operation failed.&lt;/p&gt;

&lt;p&gt;To a promise, we can attach 3 methods:&lt;/p&gt;

&lt;p&gt;.then(): Gets called after a promise resolved.&lt;br&gt;
.catch(): Gets called after a promise rejected.&lt;br&gt;
.finally(): Always gets called, whether the promise resolved or rejected.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The .then method receives the value passed to the resolve method.&lt;/li&gt;
&lt;li&gt;The .catch method receives the value passed to the rejected method
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getUserFromMySQL(custId)
.then((result) =&amp;gt; {
    console.log(result)
})
.catch((err) =&amp;gt; {
    console.log(`Something went wrong!! ${err}`)
})
.finally(() =&amp;gt; {
    console.log('Promise all done!!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Creating and Using a Promise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
//Creating
let somePromise = new Promise((resolve, reject) =&amp;gt; {
    // Some asynchronous operation
    let success = true; // This could be the result of the operation

    if (success) {
        resolve("Operation successful");
    } else {
        reject("Operation failed");
    }
});

//Using

somePromise
    .then(result =&amp;gt; {
        console.log(result); // "Operation successful"
    })
    .catch(error =&amp;gt; {
        console.error(error); // "Operation failed"
    })

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;lt; Promise Execution Behind The Scenes &amp;gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. new Promise Constructor function is called. It also receives a executor function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;new Promise((resolve, reject) =&amp;gt; {&lt;br&gt;
    //Some Async Stuff Here.&lt;br&gt;
})&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;New Promise object is created in memory. This object contains some internal slots like PromiseState, PromiseResult, PromiseFulfillReactions, PromiseRejectReactions and PromiseIsHandled. {We cannot access these internal slots}&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PromiseState will be pending if the promise is not resolved or rejected.&lt;/p&gt;

&lt;p&gt;// Initially:&lt;br&gt;
// PromiseState: "pending"&lt;br&gt;
// PromiseResult: undefined&lt;br&gt;
// PromiseFulfillReactions: []&lt;br&gt;
// PromiseRejectReactions: []&lt;br&gt;
// PromiseIsHandled: false&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg55n4nw59d7v040jm1x7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg55n4nw59d7v040jm1x7.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We can resolve or reject by calling resolve or reject that are made available to use by executor function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When we call resolve, the PromiseState is set to fulfilled.&lt;/p&gt;

&lt;p&gt;// After resolve is called:&lt;br&gt;
// PromiseState: "fulfilled"&lt;br&gt;
// PromiseResult: undefined --&amp;gt; As we have not passed anything while calling resolve()&lt;br&gt;
// PromiseFulfillReactions: [onFulfilled handler]&lt;br&gt;
// PromiseRejectReactions: []&lt;br&gt;
// PromiseIsHandled: false&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea5pba6l30utd30s9p5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea5pba6l30utd30s9p5u.png" alt="Image description" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resolving or Rejecting with some data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9qcf86utfs2r9yknl7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9qcf86utfs2r9yknl7j.png" alt="Image description" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using .then and .catch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getCarDetails = new Promise((resolve, reject) =&amp;gt; {
    const customerId = 'Elon Musk';
    readBillsFromCassandra(customerId, (error, data) =&amp;gt; {
        if (error) {
            reject('DB Client Not Ready!!');
        } else {
            resolve(data);
        }
    });
});

function readBillsFromCassandra(custId, callback) {
    console.log(`Fetching data from Cassandra keyspace for ${custId}`);
    // Simulating async data fetching with a timeout
    setTimeout(() =&amp;gt; {
        // Simulate successful data retrieval
        callback(null, {"car": "Tesla", "color": "black", "type": "EV"});
        // To simulate an error, uncomment the following line
        // callback(new Error('Cassandra error'), null);
    }, 1000);
}

getCarDetails
    .then((result) =&amp;gt; {
        console.log(`Result of promise is ${JSON.stringify(result)}`);
    })
    .catch((error) =&amp;gt; {
        console.log(`Something went wrong, Error: ${error}`);
    });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When resolve is called, it gets added to the call stack, Promise state is set to fulfilled, result is set to the value we pass to the resolve, and the promise reaction record handler receives that promise result &lt;em&gt;{"car": "Tesla", "color": "black", "type": "EV"}&lt;/em&gt; in above example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;lt; Code Flow BTS &amp;gt;&lt;/p&gt;

&lt;p&gt;Example 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Promise((resolve) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        resolve('Done!')
    }, 1000);
})
.then((result) =&amp;gt; {
    console.log('Result is ', result)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;new Promise constructor added to call stack and this creates the promise object.&lt;/li&gt;
&lt;li&gt;The executor function (resolve) =&amp;gt; { setTimeout(...) } is executed immediately.&lt;/li&gt;
&lt;li&gt;setTimeout gets added to call stack and registers a event-callback pair in Node API. Timer Starts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new Promise constructor completes, and the Promise is now pending, waiting to be resolved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next line, The .then method is called on the Promise object.&lt;/li&gt;
&lt;li&gt;Timeout achieved, callback we passed to setTimeOut is now added to Task Queue/Callback Queue.&lt;/li&gt;
&lt;li&gt;From task queue it goes to Call stack and gets executed. Promise state changes to fulfilled.&lt;/li&gt;
&lt;li&gt;.then handler now moves to micro task queue.
(result) =&amp;gt; { console.log('Result is', result) } when the Promise is resolved. The callback is added to the micro task queue (also known as the job queue).&lt;/li&gt;
&lt;li&gt;The JavaScript runtime continues to execute other code (if any) or sits idle, checking the event loop.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;setTimeout callback is popped out after execution, handler function moves to call stack and gets executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When our handler was in micro task queue, our other tasks in our code keeps on executing, only when the call stack is empty this handler gets added to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This means we can handle the promise results in a Non Blocking Way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;.then itself also creates a promise record. Which allows us to chain .then to each other, like below.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
new Promise((resolve) =&amp;gt; {
    resolve(1)
})
.then((result) =&amp;gt; {
    return result * 2;
})
.then((result) =&amp;gt; {
    return result * 3;
})
.then((result) =&amp;gt; {
    console.log(result) //Output: 6
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example 2 &amp;lt; Code Flow BTS &amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
new Promise((resolve) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        console.log(1)
        resolve(2)
    }, 1000);
})
.then((result) =&amp;gt; {
    console.log(result)
});

console.log(3);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output Sequence&lt;br&gt;
3&lt;br&gt;
1&lt;br&gt;
2&lt;/p&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Main Execution Context:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;new Promise((resolve) =&amp;gt; {...}) is encountered, and the Promise constructor is called. Which creates a Promise Object with PromiseState: pending&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promise Executor Function:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The executor function (resolve) =&amp;gt; { setTimeout(...) } is executed immediately.&lt;br&gt;
setTimeout is called with a callback and a delay of 1000 milliseconds. It registers an event-callback pair.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding .then Handler:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The .then method is called on the Promise object.&lt;br&gt;
The callback (result) =&amp;gt; { console.log(result) } is registered to be called once the Promise is resolved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logging 3 to the console.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;console.log(3) is executed immediately.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Loop and Task Execution:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The JavaScript runtime continues executing other code (if any) or sits idle, checking the event loop.&lt;br&gt;
After 1000 milliseconds, the callback passed to setTimeout is moved from the macro task queue to the call stack.&lt;/p&gt;

&lt;p&gt;The callback () =&amp;gt; { console.log(1); resolve(2); } is executed.&lt;/p&gt;

&lt;p&gt;console.log(1) is executed, logging 1 to the console.&lt;/p&gt;

&lt;p&gt;resolve(2) is called, which changes the state of the Promise from pending to fulfilled with the value 2.&lt;/p&gt;

&lt;p&gt;The .then callback (result) =&amp;gt; { console.log(result) } is enqueued in the micro task queue.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microtask Queue Execution:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the current macrotask (the setTimeout callback) completes, the event loop checks the microtask queue.&lt;/p&gt;

&lt;p&gt;The .then callback (result) =&amp;gt; { console.log(result) } is dequeued from the microtask queue and moved to the call stack.&lt;/p&gt;

&lt;p&gt;The .then callback is executed with result being 2.&lt;br&gt;
console.log(result) is executed, logging 2 to the console.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Async/Await
&lt;/h2&gt;

&lt;p&gt;ES7 introduced a new way to add async behaviour in JavaScript and make easier to work with promises based code!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvj74rzs3pzgpxgjtfgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvj74rzs3pzgpxgjtfgj.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, Let's analyse the behaviour changes when we add a keyword 'async' in front of a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = () =&amp;gt; {
    //If we do not return anything by default undefined is returned.
}

console.log(doWork()); //Output: undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, adding async&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = async () =&amp;gt; {
    //If we do not return anything by default undefined is returned.
}

console.log(doWork()); //Promise { undefined }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Hence, *&lt;em&gt;Async functions always returns a promise, and those promise are fulfilled by the value developer choose to return from the function. *&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, lets explicitly return a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = async () =&amp;gt; {
    return 'John Wick'
}

console.log(doWork()); //Promise { 'John Wick' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the return value of doWork function here is not a string, instead it is a Promise that gets fulfilled with this string 'John Wick'.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since, we are getting a promise in return, we can use .then and .catch methods.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = async () =&amp;gt; {
    //throw new Error('Db client not connected!')
    return 'John Wick'
}

doWork()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output: My name is John Wick&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If doWork throws an error, it is same as reject promise, and will be catched. Uncomment throw error to stimulate .catch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Await Operator&lt;/p&gt;

&lt;p&gt;Old Way&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const add = (a, b) =&amp;gt; {
    return new Promise((resolve, reject) =&amp;gt; {
        //setTimeOut is used to stimulate Async opearation. Here it can be any thing, like REST API call, or Fetching data from Database.
        setTimeout(() =&amp;gt; {
            resolve(a + b)
        }, 2000)
    })
}


add(1, 3)
.then((result) =&amp;gt; {
    console.log(`Result received is ${result}`)
})
.catch((err) =&amp;gt; {
    console.log(`Received error: ${err}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With using Async-Await&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const add = (a, b) =&amp;gt; {
    return new Promise((resolve, reject) =&amp;gt; {
        //setTimeOut is used to stimulate Async opearation. Here it can be any thing, like REST API call, or Fetching data from Database.
        setTimeout(() =&amp;gt; {
            resolve(a + b)
        }, 2000)
    })
}

const doWork = async () =&amp;gt; {
    try {
        const result = await add(1, 3);
        console.log(`Result is ${result}`);

    } catch (err) {
        console.log(`Received error: ${err}`)
    }
}

doWork()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This way JavaScript's async and await keywords allow developers to write asynchronous code in a style that resembles synchronous code. This can make the code easier to read and understand.&lt;/li&gt;
&lt;li&gt;The doWork function is declared with the async keyword, making it an asynchronous function. This allows the use of the await keyword inside it.&lt;/li&gt;
&lt;li&gt;Within doWork, the await keyword is used before calling add(1, 3). This pauses the execution of doWork until the Promise returned by add is resolved.&lt;/li&gt;
&lt;li&gt;While the execution is paused, other operations can continue (i.e., the event loop remains unblocked).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Async and Await doesn't make things faster, it's just makes things easier to work with. Check below snippet for doWork&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = async () =&amp;gt; {
    try {
        const sum = await add(1, 3); //Wait 2 seconds
        const sum1 = await add(sum, 10);//Wait 2 seconds
        const sum2 = await add(sum1, 100);//Wait 2 seconds
        console.log(`Final sum is ${sum2}`) //Final sum is 114
    } catch (err) {
        console.log(`Received error: ${err}`)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Out all 3 functions calls runs in order, other asynchronous things happening behind the scenes.&lt;/li&gt;
&lt;li&gt;If first await promise rejects, none of the code down below that would run.&lt;/li&gt;
&lt;li&gt;await calls operator sequentially, sum2 will not kick off until we get a value for sum. In some cases this is desired.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Taking below example where sum, sum2, sum3 are not dependent&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const doWork = async () =&amp;gt; {
    try {
        const sum = await add(1, 3);
        const sum2 = await add(4, 10);
        const sum3 = await add(100, 200);
        return `${sum}, ${sum2}, ${sum3}`
    } catch (error) {
        console.log(`Something went wrong! Error: ${error}`)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want all the sum simultaneously by not blocking each other we can rewrite the above code as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getAllSum() {
    let [
        sum,
        sum2,
        sum3
    ] = await Promise.all([
        add(1, 3),
        add(4, 10),
        add(100, 200)
    ]);
    return `${sum}, ${sum2}, ${sum3}`; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the problem with Promise chaining is that, it is difficult to have all values in same scope. For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(1, 1)
.then((sum) =&amp;gt; {
    console.log(sum)
    return add(sum, 10);
})
.then((sum2) =&amp;gt; {
    console.log(sum2)
})
.catch((err) =&amp;gt; {
    console.log(err)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What if we want to have access to both sum at the same time to do something like save in database. We would have to create a variable in parent scope and reassign them in .then.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In async await, we have access to all individual sums in the same scope.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://dev.to/rajatoberoi/javascript-main-concepts-in-depth-part-2-2mfn"&gt;click for Part 2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>backenddevelopment</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding the Event Loop, Callback Queue, and Call Stack &amp; Micro Task Queue in JavaScript</title>
      <dc:creator>Rajat Oberoi</dc:creator>
      <pubDate>Tue, 18 Jun 2024 08:57:35 +0000</pubDate>
      <link>https://dev.to/rajatoberoi/understanding-the-event-loop-callback-queue-and-call-stack-in-javascript-1k7c</link>
      <guid>https://dev.to/rajatoberoi/understanding-the-event-loop-callback-queue-and-call-stack-in-javascript-1k7c</guid>
      <description>&lt;h2&gt;
  
  
  Call Stack: Simple Data structure provided by the V8 Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript executes code using a Call Stack, which tracks the currently executing function.&lt;/li&gt;
&lt;li&gt;Main function (the entire script) is automatically added to the call stack.&lt;/li&gt;
&lt;li&gt;Functions are added to the call stack when called and removed once executed.&lt;/li&gt;
&lt;li&gt;JavaScript is single-threaded, meaning only one task is processed in the call stack at a time.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Basic Example

const x = 1;
const y = x + 2;
console.log('Sum is', y);

/*

- This code gets wrapped in main() and main is added to Call Stack.
- log('Sum is 3') added to call stack.
- On console we would get 'Sum is 3'. Now log function is finished and gets removed from Call Stack.
- Now end of script, main function gets popped out of Call Stack.
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const listLocations = (locations) =&amp;gt; {
    locations.forEach((location) =&amp;gt; {
        console.log(location);
    });
}

const myLocation = ['Delhi', 'Punjab'];
listLocations(myLocation)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Main function gets pushed onto the call stack.&lt;/li&gt;
&lt;li&gt;Line 1 we are declaring the function but not calling it, hence it will not get added to call stack.&lt;/li&gt;
&lt;li&gt;Line 7 we are defining our location array.&lt;/li&gt;
&lt;li&gt;Line 8 Function call, So it is going to be pushed to call stack and is the top item there.&lt;/li&gt;
&lt;li&gt;listLocations will start running. pushed to call stack.&lt;/li&gt;
&lt;li&gt;forEach is a function call so gets added to call stack. forEach calls anonymus function one time for each location.&lt;/li&gt;
&lt;li&gt;anonymous('Delhi) function gets added to call stack with argument Delhi.&lt;/li&gt;
&lt;li&gt;Now console.log function gets added to call stack. It prints Delhi, and finishes. and pops out.&lt;/li&gt;
&lt;li&gt;anonymous('Delhi) finishes and pops out.&lt;/li&gt;
&lt;li&gt;forEach is not done yet hence does not pops out. anonymous('Punjab) gets added to call stack.&lt;/li&gt;
&lt;li&gt;Now console.log function gets added to call stack. It prints Punjab, and finishes. and pops out.&lt;/li&gt;
&lt;li&gt;forEach is completed and hence poped out of call stack.&lt;/li&gt;
&lt;li&gt;listLocations is done, hence pops out.&lt;/li&gt;
&lt;li&gt;Script is completed. main() pops out.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Callback Queue
&lt;/h2&gt;

&lt;p&gt;It's job is to maintain a list of all of the callback functions that needs to be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log('Starting Up!');

setTimeout(() =&amp;gt; {
    console.log('Two Seconds!');
}, 2000);

setTimeout(() =&amp;gt; {
    console.log('Zero Seconds!');
}, 0);

console.log('Finishing Up!');

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;main() pushed to call stack.&lt;/li&gt;
&lt;li&gt;Line 3: setTimeout pushed to call stack.
&amp;lt; setTimeout is not part of JS V8 but is part of NodeJS. It's implementation is in C++ provided by NodeJs.&lt;/li&gt;
&lt;li&gt;setTimeout when called registers an event which is an event-callback pair. Event here is wait 2 seconds and callback is the function to run.
Another example of event-callback pair is wait for database request to complete and then run the callback that does something with the data.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This new event i.e. setTimeout function is popped and is registered in Node APIs. 2 Seconds clock starts ticking down.&lt;br&gt;
While waiting for those 2 seconds we can do other stuff &amp;lt; Non Blocking nature of node &amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line 7: setTimeout registers another event in Node API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now timeout 0 seconds are up, now the callback needs to be executed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Callback Queue comes in picture: It's job is to maintain a list of all of the callback functions that needs to be executed. Front item gets executed first.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;callback of setTimeout with 0 seconds timeout gets added to queue so that it can be executed.
But to get executed it needs to be added on Call Stack, that's where function go to run.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, here Event Loops comes in picture, it looks at the call stack and callback queue, If call stack is empty then it will run items from callback queue. &amp;lt; This is the reason 'Finishing Up!' logged before 'Zero Seconds!' as main was in call stack, event loop is waiting for main to get popped out&amp;gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;log('Zero Seconds!') gets added to call stack. and message is printed on console.&lt;/li&gt;
&lt;li&gt;main is completed and pops out.&lt;/li&gt;
&lt;li&gt;Event loop takes item from call back queue and push to call stack. 'Zero Seconds!' prints.&lt;/li&gt;
&lt;li&gt;Once 2 seconds achieved, callback('Two Seconds!') added to callback queue, moves to call stack, gets executed.
'Two Seconds!' prints.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;The delay specified in setTimeout is not the exact timing of execution but rather the minimum delay after which the callback can be added to the callback queue. &lt;/li&gt;
&lt;li&gt;The actual execution time depends on the event loop's scheduling and the availability of the call stack. This asynchronous behaviour allows JavaScript to handle non-blocking operations effectively, especially in environments like Node.js where I/O operations are common.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Non-Blocking Nature of Node.js
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Though JavaScript is single-threaded, meaning only one function can be executed at a time.&lt;/li&gt;
&lt;li&gt;it achieves non-blocking behavior using Node APIs for asynchronous tasks like setTimeout, database calls, etc.&lt;/li&gt;
&lt;li&gt;While the call stack is executing synchronous code, the environment handles asynchronous tasks in the background.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Micro Task Queue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When working with Promise, NodeJS works with micro task queue.&lt;/li&gt;
&lt;li&gt;Microtasks are queued for execution.&lt;/li&gt;
&lt;li&gt;When a Promise is resolved or rejected, its .then() or .catch() callbacks are added to the microtask queue.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In async await: When await is used inside an async function, it essentially breaks the function into two parts:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synchronous Part: The part before the await keyword executes synchronously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous Part: The part after await executes asynchronously once the awaited promise resolves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microtasks come into play when promises are resolved inside async functions using await. After the awaited promise resolves, the callback (or subsequent async code) following the await is placed in the Microtask Queue for execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Event Loop prioritise the microtask queue. Microtasks have higher priority than macrotasks (such as setTimeout callbacks or event handlers), which means they are executed as soon as the call stack is empty and before the event loop moves to the next macrotask.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;First micro task queue is emptied then event loop moves to callback queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After each task picked from callback queue and pushed to call stack, event loop will check micro task queue.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Structured summary:
&lt;/h2&gt;

&lt;p&gt;Call Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript executes code using a Call Stack, which tracks the currently executing function.&lt;/li&gt;
&lt;li&gt;Main function (the entire script) is automatically added to the call stack.&lt;/li&gt;
&lt;li&gt;Functions are added to the call stack when called and removed once executed.&lt;/li&gt;
&lt;li&gt;JavaScript is single-threaded, meaning only one task is processed in the call stack at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Asynchronous Behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Though JavaScript is single-threaded, it achieves non-blocking behavior using Node APIs for asynchronous tasks like setTimeout, database calls, etc.&lt;/li&gt;
&lt;li&gt;These APIs handle long-running tasks in the background, allowing other synchronous code to execute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Callback Queue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After an asynchronous task is complete, its callback is added to the Callback Queue.&lt;/li&gt;
&lt;li&gt;The Event Loop checks whether the Call Stack is empty and, if so, pushes callbacks from the queue to the call stack.&lt;/li&gt;
&lt;li&gt;Example: setTimeout(() =&amp;gt; console.log('Hello'), 0) will be executed after the synchronous code finishes, despite the 0ms timeout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Event Loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Loop continuously checks if the call stack is empty.&lt;/li&gt;
&lt;li&gt;It then processes tasks from the Callback Queue or Microtask Queue (like Promise callbacks).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Microtask Queue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microtasks are usually created by promises.&lt;/li&gt;
&lt;li&gt;When a promise is resolved or rejected, the corresponding .then() or .catch() handler is added to the Microtask Queue.&lt;/li&gt;
&lt;li&gt;Microtasks have higher priority than Macrotasks (like setTimeout callbacks).&lt;/li&gt;
&lt;li&gt;Before handling any macrotasks from the callback queue, the event loop checks and clears the Microtask Queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Execution Order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promises and async functions utilize the microtask queue for their resolution/rejection handlers.&lt;/li&gt;
&lt;li&gt;Example:&lt;/li&gt;
&lt;li&gt;Promises' .then() callbacks run before setTimeout callbacks, even if the timeout is 0ms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Summary of Execution Order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Synchronous code executes first (added to the call stack).&lt;/li&gt;
&lt;li&gt;Once the call stack is empty, Microtasks (e.g., resolved promises) are handled.&lt;/li&gt;
&lt;li&gt;After the microtask queue is cleared, Macrotasks (e.g., setTimeout, I/O callbacks) are processed from the Callback Queue.&lt;/li&gt;
&lt;li&gt;This explains why promises' .then() callbacks are executed before setTimeout callbacks, even with a 0ms timeout, and how JavaScript manages non-blocking operations effectively.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>asynchronous</category>
    </item>
    <item>
      <title>Mastering OOP: Encapsulation, Abstraction, Inheritance, and Polymorphism Explained with JavaScript Examples</title>
      <dc:creator>Rajat Oberoi</dc:creator>
      <pubDate>Tue, 18 Jun 2024 07:06:04 +0000</pubDate>
      <link>https://dev.to/rajatoberoi/mastering-oop-encapsulation-abstraction-inheritance-and-polymorphism-explained-with-javascript-examples-fc</link>
      <guid>https://dev.to/rajatoberoi/mastering-oop-encapsulation-abstraction-inheritance-and-polymorphism-explained-with-javascript-examples-fc</guid>
      <description>&lt;p&gt;Four fundamental concepts of Object-Oriented Programming (OOP)&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Encapsulation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bundling the data (properties) and methods (functions) that operate on the data into a single unit, typically a class or an object.&lt;/li&gt;
&lt;li&gt;It restricts direct access to some of the object's components, which can help prevent the accidental modification of data. Instead, interactions with the data are done through well-defined interfaces (methods).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;lt; Procedural way of code &amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let baseSalary = 30000;
let overtime = 10;
let rate = 20;

function getWage(baseSalary, overtime, rate) {
    return baseSalary + (overtime * rate)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;lt; OOP way &amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let employee = {
    baseSalary: 30000,
    overtime: 10,
    rate: 20,
    getWage: function() {
        return this.baseSalary + (this.overtime * this.rate);
    }
}

console.log(employee.getWage())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In OOP way functions will have fewer parameters. And hence easier to manage.&lt;/li&gt;
&lt;li&gt;Parameters modeled as properties of this object.&lt;/li&gt;
&lt;li&gt;Data (baseSalary, overtime, rate) and functionality (getWage method) are encapsulated within a single object employee.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Abstraction
&lt;/h2&gt;

&lt;p&gt;Abstraction in JavaScript (or any programming language) involves hiding the complex implementation details and showing only the necessary features of an object.&lt;br&gt;
This helps in reducing complexity and increases the efficiency of the program by allowing the user to interact with the object at a higher level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Car {

    constructor(make, model, year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    startEngine() {
        this.#checkEngine();
        console.log(`${this.make} ${this.model} engine started.`);
    }

    drive() {
        console.log(`${this.make} ${this.model} is driving.`)
    }

    #checkEngine() {
        console.log('Check engine...')
    }
}

const myCar = new Car('Tata','Punch', 2024);
myCar.startEngine();
myCar.drive();
// myCar.#checkEngine(); //--&amp;gt; SyntaxError: Private field '#checkEngine' must be declared in an enclosing class
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Private method checkEngine cannot be accessed outside the class because it has a private identifier.  #checkEngine is an example of a private method (a feature introduced in ES2022).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The startEngine method provides a simple interface for the user, while the complex logic inside #checkEngine is hidden, demonstrating abstraction.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Inheritance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Helps us to prevent redundant code.&lt;/li&gt;
&lt;li&gt;Allows a class to inherit properties and methods from another class. In JavaScript, inheritance can be implemented using the class syntax with the extends keyword.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Base class
class Vehicle {
    constructor(make, model, year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    drive() {
        console.log(`${this.make} ${model} driving.`)
    }
}

//The Car class inherits from the Vehicle class. This means that Car has access to the properties and methods defined in Vehicle
class Car extends Vehicle {
    constructor(make, model, year, color) {
        super(make, model, year);
        this.color = color;
    }

    getColor() {
        console.log(`Color of ${this.make} ${this.model} is ${this.color}`)
    }
}

const myCar = new Car('Tata', 'Punch', '2024', 'Grey');
myCar.getColor()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Polymorphism
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Poly means Many, morphism means Forms.&lt;/li&gt;
&lt;li&gt;In polymorphism the same method results in different actions depending on the object it is acting upon.&lt;/li&gt;
&lt;li&gt;In programming terms, the remote control calls the power method, and each device has its own implementation of what happens when the power method is called.&lt;/li&gt;
&lt;li&gt;This is polymorphism: the same method (power) results in different actions depending on the object it is acting upon (TV, DVD player, or radio).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// Base class
class Device {
    power() {
        throw new Error('power method must be implemented');
    }
}

// Derived class for TV
class TV extends Device {
    power() {
        console.log('Turning TV on or off.');
    }
}

// Derived class for DVD Player
class DVDPlayer extends Device {
    power() {
        console.log('Turning DVD Player on or off.');
    }
}

// Derived class for Radio
class Radio extends Device {
    power() {
        console.log('Turning Radio on or off.');
    }
}

// Function that demonstrates polymorphism
function useRemoteControl(device) {
    device.power();
}

// Usage
const myTV = new TV();
const myDVDPlayer = new DVDPlayer();
const myRadio = new Radio();

useRemoteControl(myTV);        // Output: Turning TV on or off.
useRemoteControl(myDVDPlayer); // Output: Turning DVD Player on or off.
useRemoteControl(myRadio);     // Output: Turning Radio on or off.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
