Blog

  • JavaScript – Throttling

    What is Throttling?

    Throttling is a technique that limits how many times a function can be called in a specific period of time. It improves the speed and responsiveness of web sites by implementing event listeners that do heavy or expensive tasks such as animations, scrolling, resizing, getting data, etc.

    For example, if you have a function that collects data from an API every time the user scrolls down the page, you can throttle it so that it only makes one request per second instead of hundreds as the user scrolls. This prevents you from overloading the server or browser with unnecessary queries, hence reducing bandwidth usage.

    Why use Throttling in JavaScript?

    JavaScript Throttling can increase application performance by setting a set rate of function execution.

    A Throttle function generates function calls at predefined intervals, keeping the program from lagging or becoming overloaded. As a result the server will handle requests in a certain order and at a predetermined time.

    Implement Throttling in JavaScript

    Here are the steps you can follow to create Throttling in JavaScript −

    • Create a Throttle Function: Define a function that accepts a callback and a delay to adjust the execution frequency over time.
    • Track Last Run Time: Save the timestamp from the last function called to see if the wait has been completed.
    • Check Time Interval: For each trigger, compare the current time to the last execution time; execute only if enough time has passed.
    • Return the Throttled Function: Create a new function that only executes the old callback when the specified time period is met.

    How Throttling work in JavaScript?

    Let us look at an example to better understand JavaScript and throttling. Consider this scenario: we have added a scroll event listener to a web page and configured it such that when the user scrolls, he sees the desired information.

    But if the user scrolls frequently, the web page will soon generate hundreds of events. To address this issue, we will throttle the event so that it is only triggered after a second of the previous event. This results in a single callback every second. The end user will see the same results, but they will be far more computationally efficient.

    Now Let us understand it with the help of the example below. In the following example, we will use the throttle mechanism to distinguish between throttling and non-throttling conditions.

    Without throttling Function

    Without throttling, a function can be called too quickly, causing performance issues, excessive resource usage and a possibly unpleasant user experience.

    Example

    In this example, we add an event listener to a button without throttling. Each click triggers the callback immediately and sending the message ‘button is clicked’ to the console with no rate limit.

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" 
       content="width=device-width, 
       initial-scale=1.0"><title>Document</title></head><body><button id="pressButton">Press Me</button><script>
          // Selected button with the given id
          const button = document.
          querySelector("#pressButton");
          
          // Add event listener to the button 
          // to listen to the click event
          button.addEventListener("click", () => {
             console.log("The button has been pressed");
          });
       </script></body></html>

    Output

    This will produce the below result −

    JavaScript Without Throttling

    With Throttling Function

    Throttling limits the number of function invocations. For example, you could choose to execute a function at most once per 1500 milliseconds. This prevents the function from being called too frequently, which results in smoother performance.

    Example

    In this example we throttle a button click event by limiting the ‘Button has been pressed!’ log to once per 1500 milliseconds, regardless of how quickly we click.

    Following is the simple demonstration with throttling function −

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" 
          content="width=device-width, 
          initial-scale=1.0"><title>Document</title></head><body><button id="pressButton">Press Me</button><script>
          const button = document.querySelector("#pressButton");
    
          // Throttling Function
          const limitFunctionCall = (callback, waitTime) => {
    
             // Previously called time of the function
             let lastCalled = 0;
             return (...args) => {
                // Current called time of the function
                let currentTime = new Date().getTime();
    
                // Logging the difference
                // between previously called and current called timings
                console.log("Time difference:", currentTime - lastCalled, "Wait time:", waitTime);
    
                // If the difference is greater than waitTime, call the function again
                if (currentTime - lastCalled > waitTime) {
                   lastCalled = currentTime;
                   // Return the function 
                   return callback(...args);
                }
             }
          }
          button.addEventListener("click",
             limitFunctionCall(() => {
             console.log("Button has been pressed!")
             }, 1500));
        </script></body></html>

    Output

    This will generate the below result −

    [Log] Time difference: - 1729667433711 - "Wait time:" - 1500 (example.html, line 28)
    [Log] Button has been pressed! (example.html, line 41)
    [Log] Time difference: - 1016 - "Wait time:" - 1500 (example.html, line 28)
    [Log] Time difference: - 1599 - "Wait time:" - 1500 (example.html, line 28)
    [Log] Button has been pressed! (example.html, line 41)
    [Log] Time difference: - 416 - "Wait time:" - 1500 (example.html, line 28)
    [Log] Time difference: - 866 - "Wait time:" - 1500 (example.html, line 28)
    

    Use cases for Throttling

    A throttle function operates at a fixed rate to prevent the app from lagging or overwhelming the server when performing a time-consuming task or request. The following are some common applications for the throttle function.

    • In Gaming: In games, players press buttons to perform actions like punching and shooting. If they press too quickly we can use throttle to limit the frequency of activities like once per second.
    • Ads and Scrolling: When users scroll we regularly load and animate content. Scrolling too quickly can lead to the app to slow down. Throttling keeps things functioning smoothly by limiting actions.
    • Button Clicks:Some programs, like those used at ATMs, take longer to complete tasks. Throttling prevents users from pressing the button too quickly.
    • Pointer (Mouse) Events:Moving the mouse can lead to events to occur too frequently. Throttling controls how frequently these events occur to ensure that everything runs properly.
    • API Calls: If an app makes too many API requests quickly it can slow down loading. Throttling limits requests to prevent problems.

    Summary

    JavaScript Throttling is an approach that restricts function execution to a specific number of times. It ensures that a function is executed on a consistent basis, regardless of how many times it has been invoked.

  • JavaScript – Temporal Dead Zone (TDZ)

    The Temporal Dead Zone (TDZ) is a JavaScript concept which explains how variables behave when let and const are used. It means that before a variable can be used it needs to be defined. This takes place in between the declaration of the variable and the start of the block like a function or loop.

    Why Does Temporal Dead Zone Happen?

    When you declare a variable in JavaScript using let or const, a space is created for it. But until the variable is defined, it stays in the “dead zone.” If you try to use JavaScript before the declaration, it will raise an error.

    • Block scope: It applies to the let and const variables. This means they are only allowed in the block where they are declared.
    • Cannot Access: A variable cannot be accessed until it is declared in the same block. This prevents errors in your code.

    Examples of Temporal Dead Zone

    Following are some examples of Temporal Dead Zone −

    Example 1

    In this example, we will try to log myVar before it is declared. JavaScript throws a ReferenceError because myVar is inside the TDZ. You have to define myVar before you can use it.

    // This will throw an error
    console.log(myVar);let myVar =5;

    Output

    This will generate the below result −

    ReferenceError: Cannot access 'myVar' before initialization
    

    Example 2

    In the MyFunction function, we tried to log myNum before declaring it. Because myNum has not yet been defined it remains in the TDZ when we call the function which is causing an error.

    functionmyFunction(){// This will throw an error
       console.log(myNum);let myNum =10;}myFunction();

    Output

    As a result, the following will happen −

    ReferenceError: Cannot access 'myNum' before initialization
    

    Example 3

    In this example we try to log myConst before using it in an if block. As with let is the variable in the TDZ, which causes an error.

    if(true){// This will throw an error
       console.log(myConst);const myConst =20;}

    Output

    This will lead to the following result −

    ReferenceError: Cannot access 'myConst' before initialization
    

    How to avoid TDZ in JavaScript?

    Preventing TDZ issues needs declaring variables before trying to access them. By giving as a way to detect possibilities when a variable is accessed before it is declared, it promotes more easy and predictable code. Understanding TDZ reduces the possibility of JavaScript runtime errors and facilitates the development of code that follows best practices.

    For avoiding the Temporal Dead Zone (TDZ) in JavaScript you can follow the simple rules defined below −

    Declare Variables at the Beginning

    Declare your variables at the start of a block (like a function or an if statement) to be sure they are available when you need them. This keeps them outside of the TDZ.

    functionexampleFunction(){// Declare at the toplet count =0; 
       console.log("Initial count:", count); 
       count =5;
       console.log("Updated count:", count); 
       console.log("End of exampleFunction");}// Example usage:exampleFunction();

    Output

    This code will produce the following outcome −

    Initial count: 0
    Updated count: 5
    End of exampleFunction
    

    Avoid Using Variables Before Declaration

    An easy method to avoid TDZ refers to is to avoid using variables before they are defined. Check your code to ensure that no variables are called or recorded before they are specified as let or const.

    // Declare the variable firstlet num =10;// Now safe to use
    console.log(num);

    Output

    This will produce the following output −

    10
    

    Use var Only If Necessary

    Unlike let and const, variables declared using var are set to the top of their scope and initialized with undefined, so they do not have a TDZ. But it is preferable to use var only when absolutely necessary because it introduces additional defining issues that can make code difficult to understand.

    // No error, but outputs undefined
    console.log(a);var a =5;

    Output

    This will create the below outcome −

    undefined
    

    Organize Code to Minimize TDZ Errors

    To keep your code clean and organized you should place variable declarations at the beginning of your functions or blocks. This way, they are disclosed early and ready when you need them.

    functioncalculateArea(radius){
       console.log("Starting calculation...");if(radius >0){
          console.log("Radius is greater than 0, proceeding with calculation.");// Declare variables before using themlet pi =3.14;let area = pi * radius * radius;
          console.log("Calculated area:", area);return area;}else{
          console.log("Radius is not greater than 0, returning 0.");}return0;}// Example usagecalculateArea(5);calculateArea(-3);

    Output

    This will lead to the following outcome −

    Starting calculation...
    Radius is greater than 0, proceeding with calculation.
    Calculated area: 78.5
    Starting calculation...
    Radius is not greater than 0, returning 0.
  • JavaScript – Supercharged Sorts

    The Array.sort() method in JavaScript is an essential tool for any developer that works with data sets. While sorting a list of numbers or words is simple, sorting arrays of objects based on numerous criteria becomes more complicated. In this chapter, we will look at various ways for making full use of Array.sort() for creating complicated, multi-property sorts.

    Basics of Sorting

    Before we go into advanced methods, we will go over the fundamentals of how Array.sort() operates. The sort() method accepts an optional callback function that specifies the sorting order. This comparator function accepts two parameters (a and b) and returns a numerical value −

    • If the returned value is negative, sort a before b.
    • If the returned value is positive, sort b before a.
    • If the returned result is 0, the order of a and b is unaltered.

    Below is a very simple JavaScript example code for sorting an array of numbers in the ascending order −

    const numbers =[12,7,19,3,8,5,10,15];// Sorting the array in descending order
    numbers.sort((a, b)=> b - a);// Printing the sorted array
    console.log(numbers);

    Output

    This will generate the below result −

    [ 19, 15, 12, 10, 8,  7,  5,  3 ]
    

    The comparator (a, b) => a – b returns a negative value when a < b, a positive value whenever a > b, and 0 when a === b, which fulfills the contract Array.sort() requires.

    Chaining Multiple Sort Criteria

    Things become more interesting when we have to sort an array of objects based on multiple properties. Look at an array of items.

    const products =[{ name:'Smartphone', price:699.99, rating:4.7},{ name:'Headphones', price:129.99, rating:4.3},{ name:'Tablet', price:399.99, rating:4.1},{ name:'Smartwatch', price:199.99, rating:4.5},];

    Assume we want to arrange these products by price in ascending order, followed by rating in descending order as a tiebreaker for items with identical prices. We can chain the comparators together using the boolean OR operator (||) −

    products.sort((a, b)=> 
       a.price - b.price || b.rating - a.rating
    );

    Here’s how it works −

    • The first comparator, a.price minus b.price, is evaluated. If the prices differ, it yields a non-zero value and the || short-circuits, resulting in price sorting.
    • If the prices are the same, a.price – b.price equals 0. The || then evaluates the second comparator, b.rating – a.rating, and sorts by descending rating.

    This pattern allows us to chain as many comparators as we need −

    products.sort((a, b)=> 
       a.price - b.price || 
       b.rating - a.rating ||
       a.name.localeCompare(b.name));

    Items with the same price and rating are now sorted alphabetically by name to determine the final tiebreaker.

    Creating Reusable ‘sortBy’ Functions

    While the chained comparator approach is effective, it can result in difficult-to-read and code that is repetitive if we need to sort by the same criteria multiple times. We can make our code more modular by introducing generic “sortBy” functions for each property −

    constbyPrice=(a, b)=> a.price - b.price;constbyRating=(a, b)=> b.rating - a.rating;constbyName=(a, b)=> a.name.localeCompare(b.name);
    
    products.sort((a, b)=>byPrice(a, b)||byRating(a, b)||byName(a, b));

    This improves the sort chain’s readability and allows each comparator to be reused. But we are still writing some repetitive code for each property. Let’s see if we can improve.

    Higher-Order ‘sortBy’ Function

    To increase re-usability, we can define a higher-order ‘sortBy’ function that accepts a property name and returns a comparator function −

    functionsortBy(prop){return(a, b)=> 
        a[prop]< b[prop]?-1:
        a[prop]> b[prop]?1:0;}const byPrice =sortBy('price');constbyRating=(a, b)=>sortBy('rating')(b, a);const byName =sortBy('name');

    The sortBy function is considered higher-order because it returns another function. It uses the closure method to capture the prop argument within the scope of the returning comparator.

    This approach allows us to simply develop comparators for any property. To sort in descending order, the byRating comparator reverses the usual (a, b) order.

    Here is the complete ES6 version with the help of arrow functions −

    constsortBy=(prop)=>(a, b)=>
      a[prop]< b[prop]?-1: 
      a[prop]> b[prop]?1:0;
    
    products.sort((a, b)=>sortBy('price')(a, b)||sortBy('rating')(b, a)||sortBy('name')(a, b));

    Summary

    In this chapter, we went over numerous ways for improving your JavaScript sorting skills.Combining several sort criteria with boolean OR logic.Refactoring Comparators into Reusable “sortBy” Functions.Developing a higher-order “sortBy” function to maximize versatility.Understanding and following these patterns will allow you to efficiently sort arrays of objects based on many properties while writing clean and maintainable code.

  • JavaScript – SQL CRUD Operations

    This chapter will show the CRUD operations on a JavaScript object. The operations are Create, Read, Update, and Delete. We can create, modify, take input, and delete objects with these actions. A JavaScript object consists of a collection of keys, values, or properties/attributes, and entries. Values can be any type of data, including arrays, JavaScript functions, and more.

    CRUD Operations

    Create, read, update, and delete is what CRUD stands for. These are permanent storage’s four primary purposes. Also, any function that is carried out in relational database applications and translated to a typical HTTP method, SQL statement, or DDS action can be denoted by any letter in the acronym.

    • CREATE Operations: To create a new record, execute the INSERT statement.
    • READ the Steps: Uses the primary keynoted in the input parameter to read the table records.
    • UPDATE Procedures: Uses the primary key that has been specified for a record in the WHERE clause of the statement to execute a UPDATE statement on the table.
    • DELETE processes: Removes a specific WHERE clause row.

    Syntax

    Here is the syntax for using CRUD operations in JavaScript −

    // Creating an Objectconst circle ={
       radius:10,area:function(){return Math.PI*this.radius *this.radius;}};

    CREATE Operation

    This operation is the process of creating an object or giving it with a new property. The following methods can be used to generate the object:

    • Using Object Constructor: This function allows you to create and initialize an object. The return value is assigned to a variable. The variable has a reference to the new object.
    • Using object literals: Making use of object literals Use a list of key-value pairs separated by a comma (“,” to build an object).

    Syntax

    Here is the syntax for create operation in Javascript −

    // Using Object Constructorconst obj =newObject();// Using Object Literalsconst obj ={
       key1 : value1
    }

    Example

    In the below example we will create an object with the help of the above two methods.

    const box ={ 
       height:25, 
       breadth:20,volume:function(){returnthis.height *this.breadth;}};const cube =newObject(); 
    cube.edge =10; 
    cube.volume=function(){returnthis.edge *this.edge;}; 
    
    cube.edge =15; 
    console.log(box,"Volume of the box: "+ box.volume()); 
    console.log(cube,"Volume of the cube: "+ cube.volume());

    Output

    This will produce the below result −

    { height: 25, breadth: 20, volume: [Function: volume] } Volume of the box: 500
    { edge: 15, volume: [Function (anonymous)] } Volume of the cube: 225
    

    Read Operation

    The read operation is the process of reading and accessing the values and properties of an object. The methods listed below can be used −

    • Using Destructuring Assignment: To unpack object values and allocate them to other variables in JavaScript, use the syntax known as “using destructuring assignment.”
    • Using Dot Notations: Making use of Dot Notations this syntax makes it possible to access the object attributes and items by using a [dot] or “.” symbol.
    • Using Bracket Notation: The property name enclosed in brackets “[ ]” can be retrieved from the object property using Bracket Notation.

    Syntax

    Below is the syntax for Read operation in Javascript −

    // Using dot notation
    console.log(obj.prop1)// For Nested objects
    console.log(obj.prop1.subProperty)// Using Square Brackets 
    console.log(obj['prop2'])// Using Object Destructuringconst{ key1 }= obj1;                                      
    console.log(key1);

    Example

    In the below example we will use another methods for reading the object property values.

    // Creating a new object const box ={ 
       height:25, 
       width:20,volume:function(){returnthis.height *this.width;}};const{ height }= box; 
    console.log("Box height: "+ height); 
    console.log("Box width: "+ box['width']); 
    console.log("Box volume: "+ box.volume());

    Output

    This will generate the following output −

    Box height: 25
    Box width: 20
    Box volume: 500
    

    Update Operation

    It shows that you can see and change an object’s properties. These methods can be used −

    • Using Destructuring Assignment: To unpack object values and allocate them to other variables in JavaScript, use the syntax known as “using destructuring assignment.”
    • Using Dot Notations: Making Use of Dot Notations this syntax makes it possible to access the object attributes and items by using a [dot] or “.” symbol.

    Syntax

    Below is the syntax for Update operation in Javascript −

    // Using dot notation
    obj.prop1 ="newValue";// Using brackets
    obj['prop2']="value2";

    Example

    This example shows the manipulation of the Object properties and their related values.

    const box ={ 
       height:25, 
       depth:20,volume:function(){returnthis.height *this.depth;}};// Display Initial Volume 
    console.log("Initial Volume: "+ box.volume());// Update Values // Using dot notation 
    box.height =50;// Using brackets notation 
    box['depth']=40;// Display Updated Volume 
    console.log("Updated Volume: "+ box.volume());

    Output

    This will generate the below result −

    Initial Volume: 500
    Updated Volume: 2000
    

    Delete Operation

    A delete operation is the process of removing an object property. Below is one method for doing it −

    • Using the Delete operator: The Delete keyword is used to remove the object property that comes after it.
    • Using Destructuring Assignment: To unpack object values and allocate them to other variables in JavaScript, use the syntax known as “using destructuring assignment.”

    Syntax

    Here is the syntax for Delete operation in Javascript −

    // Using delete operatordelete obj.property  
    
    // Using destructuringconst{prop1, newObj}= oldObj;

    Example

    In this example we will describe the deletion of the Object and its associated properties and values.

    const person ={ 
       firstName:'Amit', 
       yearsOld:52, 
       location:'mumbai'};// Display original person object 
    console.log("Initial person object: ", person);// Using destructuring const{ yearsOld,...updatedPerson }= person; 
    console.log("New person object without yearsOld attribute: ", updatedPerson);// Using delete operator delete person.location; 
    console.log("Person object after removing location: ", person);

    Output

    This will create the below outcome −

    Initial person object:  { firstName: 'Amit', yearsOld: 52, location: 'mumbai' }
    New person object without yearsOld attribute:  { firstName: 'Amit', location: 'mumbai' }
    Person object after removing location:  { firstName: 'Amit', yearsOld: 52 }
  • JavaScript – SessionStorage

    Session Storage in JavaScript

    The JavaScript sessionStorage object is a window object property that appears in all current browsers. The page’s protocol, host-name and port are linked to any sessionStorage data. Each window contains its own session storage. The JavaScript sessionStorage method contributes to the reliable storage of user data.

    In JavaScript, we use the getItem() method to get elements that are always stored in the session storage attribute. The storage object includes a getItem() method. It could be a JavaScript session Storage object or a local Storage object.

    Syntax

    Below is the syntax of the JavaScript SessionStorage −

    window.sessionStorage;

    Methods of SessionStorage

    To get an element from JavaScript sessionStorage we have to create the element and save it to session storage. We can get it back later. The storage object has four methods: setItem(), getItem(), removeItem(), key() and clean().

    setItem()

    Used to save information in a session storage item. Here is how you can use it in your code −

    sessionStorage.setItem("key","value");

    getItem()

    Used to retrieve and display a session storage item. Following is way you can use it in your code −

    let lastname = sessionStorage.getItem("key");

    removeItem()

    Used to delete a specific item from session storage. The following is how you can utilize it in your code −

    sessionStorage.removeItem("key");

    key()

    Used to get the name of a data item in session storage. Here is how you can utilize it in your code −

    let keyName = sessionStorage.key(index);

    clear()

    Used to clear all items in session storage. Here’s how you can put it into your code −

    sessionStorage.clear();

    Why do use sessionStorage in JavaScript

    SessionStorage can be used in many different ways. And these are the most important ones:

    • The web-page interface can be saved in session storage.
    • When the user returns to the page later, you can use sessionStorage to restore the previously saves user interface.
    • SessionStorage can also be used to transmit data between pages instead of using hidden input fields or URL parameters.

    Key Features

    Below are some key features of JavaScript’s SessionStorage −

    • Temporary Storage: Data is only stored for the duration of the session.
    • Tab-specific: Data is only accessible in the same browser tab or window.
    • Simple API: Provides simple methods for configuring, retrieving, and removing items.
    • Persistent During Reloads: Data is preserved after a page reload within the same session.
    • Storage Limit: Typically gives about 5MB of storage per origin for session data.

    Examples

    Following are some examples of the session storage −

    Example 1

    The example below shows how to use JavaScript sessionStorage with the set and get items methods. A session storage object helps us to create arrays and set data. After that, display information by calling the object’s getItem() function.

    <html><head><title>Display Data Using sessionStorage in JavaScript</title></head><body style="text-align: center;"><h4>Display Data Using sessionStorage in JavaScript</h4><p id="displayStudent"></p><p id="displayTutorial"></p><script>  
       const studentInfo = {  
          name: 'Amit',  
          rollNumber: 41,  
          website: 'Tutorialspoint',  
          learningMode: 'online',  
          age: 20,  
          subject: 'JavaScript'  
       };  
    
       const tutorialInfo = {  
          subject: 'JavaScript',  
          website: 'Tutorialspoint',  
          mode: 'online',  
          cost: 'Free',  
          targetAudience: 'students and beginners'  
       };  
    
       // Set and display studentInfo in sessionStorage
       sessionStorage.setItem("studentInfo", JSON.stringify(studentInfo));  
       console.log("Student info saved in sessionStorage.");
       let retrievedStudent = sessionStorage.getItem('studentInfo');  
       document.getElementById('displayStudent').innerHTML = retrievedStudent;  
    
       // Set and display tutorialInfo in sessionStorage
       sessionStorage.setItem("tutorialInfo", JSON.stringify(tutorialInfo));  
       console.log("Tutorial info saved in sessionStorage.");
       let retrievedTutorial = sessionStorage.getItem('tutorialInfo');  
       document.getElementById('displayTutorial').innerHTML = retrievedTutorial;  
    </script></body></html>

    Output

    This will generate the below result −

    Display Data Using sessionStorage in JavaScript
    
    {"name":"Amit","rollNumber":37,"website":"Tutorialspoint","learningMode":"online","age":19,"subject":"JavaScript"}
    
    {"subject":"JavaScript","website":"Tutorialspoint","mode":"online","cost":"Free","targetAudience":"students and beginners"}
    

    Example 2

    This example shows how to use JavaScript session storage with the set and get items methods. To display the date and time, we can use the object’s getItem() method. The array value use the get and set methods, whereas the date value writes data immediately.

    <html><head><title> Display Data Using sessionStorage in JavaScript </title></head><body style="text-align: center;"><h4> Display Data Using sessionStorage in JavaScript </h4><p id="displayStudentInfo"></p><p id="displayCurrentTime"></p><script>  
       const learnerDetails = {  
          name: 'Amit',  
          rollNumber: 52,  
          website: 'TutorialsPoint',  
          learningMode: 'online mode',  
          age: 22,  
          subject: 'JavaScript'  
       };  
       
       // Store student info in sessionStorage
       sessionStorage.setItem("learnerDetails", JSON.stringify(learnerDetails));  
       console.log("Learner details saved in sessionStorage.");
       
       // Retrieve and display student info
       let retrievedStudentInfo = sessionStorage.getItem('learnerDetails');  
       document.getElementById('displayStudentInfo').innerHTML = retrievedStudentInfo;  
       
       // Store and display current date and time
       let currentDateTime = new Date();  
       sessionStorage.currentDateTime = currentDateTime;  
       console.log("Current date and time saved in sessionStorage.");
       let retrievedDateTime = sessionStorage.getItem('currentDateTime');  
       document.getElementById('displayCurrentTime').innerHTML = retrievedDateTime;  
    </script></body></html>

    Output

    This will lead to the following result −

    Display Data Using sessionStorage in JavaScript
    {"name":"Amit","rollNumber":52,"website":"TutorialsPoint","learningMode":"online mode","age":22,"subject":"JavaScript"}
    Fri Oct 25 2024 13:14:10 GMT+0530 (India Standard Time)
    

    Example 3

    Here is an example of using sessionStorage in an HTML file with JavaScript. The sessionStorage is used to save data for the life of the session and makes it available as long as the browser tab is open.

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Session Storage Example</title></head><body><h1>Session Storage Demo</h1><label for="name">Enter your name:</label><input type="text" id="name" /><button onclick="saveName()">Save Name</button><button onclick="showName()">Show Name</button><button onclick="clearName()">Clear Name</button><p id="result"></p><script>
       // Function to save name in sessionStorage
       function saveName() {
          let name = document.getElementById('name').value;
          sessionStorage.setItem('userName', name);
          document.getElementById('result').innerText = 'Name saved in session storage!';
       }
       
       // Function to show name from sessionStorage
       function showName() {
          let name = sessionStorage.getItem('userName');
          if (name) {
             document.getElementById('result').innerText = 'Stored Name: ' + name;
          } else {
             document.getElementById('result').innerText = 'No name found in session storage!';
          }
       }   
       // Function to clear name from sessionStorage
       function clearName() {
          sessionStorage.removeItem('userName');
          document.getElementById('result').innerText = 'Name cleared from session storage!';
       }
    </script></body></html>

    Output

    So you have to open the file in a browser. Then enter a name and then click Save Name. After that you have to click Show Name to see the stored name. And click Clear Name to remove it from storage.

    Javascript SessionStorage

    Summary

    The sessionStorage allows you to store data just for a single session. When you close a browser tab or window, the sessionStorage data is automatically removed. As the sessionStorage is a Storage system object, you can handle its data using Storage-specific methods.

  • JavaScript – Selection API

    JavaScript Selection API allows us to access and change or modify the portion of a web page which is selected by the user.This includes selecting which text or elements to highlight and providing options for connecting with the selected item. But it should be noticed that the Selection API is not available in Web Workers so it can only be used in a web-page’s main thread.

    The JavaScript Selection API provides a variety of essential APIs that allow developers to access and modify certain portions of a document. These interfaces contain the Selection and Range objects, as well as a number of helpful events that occur all over the selection process.

    Selection Interface

    A Selection object shows the user-selected region of text or the cursor’s current position. Each document is given a unique selection object, which can be retrieved via document.getSelection(), or Window.getSelection() can then be examined and modified.

    A user can choose between left to right and right to left. The anchor is where the user began the selection, whereas the focus is where the user ends it. When you make a selection with a desktop mouse, the anchor is set where you pressed the mouse button and the focus is placed where you let go.

    Instance Properties

    Here is the table provided of instance properties you can use for you reference −

    PropertyDescription
    Selection.anchorNodeThis shows the part of the document where the selection starts. It will be empty if nothing was selected.
    Selection.anchorOffsetThis tells how far the starting point of the selection is from the beginning. If the selection starts in a piece of text, it shows the number of characters before it. If it starts in an element (like a paragraph or list), it shows the number of other elements before it.
    Selection.directionThis shows if the selection was made from left to right, or right to left.
    Selection.focusNodeThis shows the part of the document where the selection ends. It can also be empty if nothing was selected.
    Selection.focusOffsetSimilar to anchorOffset, this shows how far the ending point of the selection is from the beginning in the focusNode.
    Selection.isCollapsedThis is true if the selection has no length (meaning the start and end are the same point), and false if there is a range of selected text.
    Selection.rangeCountThis tells you how many separate selections are made.
    Selection.typeThis gives the type of selection. It can be “None” (no selection), “Caret” (a single point), or “Range” (a highlighted area).

    Instance Methods

    Here is the table below in which we have provided the list of instance methods of Selection Interface with its description.

    MethodsContent
    Selection.addRange()A Range object that will be added to the selection.
    Selection.collapse()Collapses the current selection to a single point.
    Selection.collapseToEnd()Collapses the selection to the end of the last range in the selection.
    Selection.collapseToStart()Collapses the selection to the start of the first range in the selection.
    Selection.containsNode()Indicates if a certain node is part of the selection.
    Selection.deleteFromDocument()Deletes the selection’s content from the document.
    Selection.empty()Removes all ranges from the selection, leaving the anchorNode and focusNode properties equal to null and nothing selected.
    Selection.extend()Moves the focus of the selection to a specified point.
    Selection.getComposedRanges() ExperimentalReturns an array of StaticRange objects, each that represents a selection that might cross shadow DOM boundaries.
    Selection.getRangeAt()Returns a Range object representing one of the ranges currently selected.
    Selection.modify()Changes the current selection.
    Selection.removeRange()Removes a range from the selection.
    Selection.removeAllRanges()Removes all ranges from the selection.
    Selection.selectAllChildren()Adds all the children of the specified node to the selection.
    Selection.setBaseAndExtent()Sets the selection to be a range including all or parts of two specified DOM nodes, and any content located between them.
    Selection.setPosition()Collapses the current selection to a single point.
    Selection.toString()Returns a string currently being represented by the selection object, i.e., the currently selected text.

    Document.getSelection()

    The getSelection() method of the Document interface returns the Selection object for this document which represents the user-selected text range or the caret’s current position. And it acts like the window.getSelection().

    Syntax

    Below is the syntax of the Document.getSelection() −

     document.getSelection()

    Parameters

    This method works without the need for any parameters.

    Return value

    This method basically returns a Selection object, or null if there is no browsing context (e.g., unattached <iframe>).

    Example

    Following is the example for showing the usage of Document.getSelection() object −

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document.getSelection Example</title></head><body><p>Select some text in this paragraph and check the console.</p><button onclick="getSelectedText()">Get Selected Text</button><script>
          function getSelectedText() {
             let selection = document.getSelection();
             if (selection.rangeCount > 0) {
                document.write("Selected text: " + selection.toString());
             } else {
                document.write("No text selected.");
             }
          }
       </script></body></html>

    Output

    To view the messages use the browser’s developer tools (usually by pressing F12) and select the “Console” tab.

    Check the below message on the console after running the above code in browser −

    Selected text: paragraph and check
    

    Window.getSelection()

    The getSelection() method of the Window interface returns the Selection object connected with the window’s document which represents the range of text selected by the user or the caret’s current position.

    Syntax

    Below is the syntax of the Window.getSelection() −

     window.getSelection()

    Parameters

    This method does not require any parameters.

    Return value

    This method returns a Selection object or null if the connected document has browsing context (e.g. if the window is an unattached <iframe>).

    Firefox gives null when a <iframe> is not displayed (e.g., display: none), whereas other browsers provide a Selection object with Selection.type set to None.

    Example

    Here is the example for showing the usage of Window.getSelection() object −

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Window.getSelection Example</title></head><body><p>Select some text in this paragraph and check the console.</p><button onclick="getSelectedText()">Get Selected Text</button><script>
          function getSelectedText() {
             let selection = window.getSelection();
             if (selection.rangeCount > 0) {
                document.write("Selected text: " + selection.toString());
             } else {
                document.write("No text selected.");
             }
          }
       </script></body></html>

    Output

    So when to run the above HTML code in your browser. There will be a text will be appear with a button “Get Selected Text”. So when you select some text and press the button then after inspecting the element you can see the below message on the console −

    Selected text: this paragraph
    

    Document: selectionchange event

    The Selection API’s selectionchange event is triggered when a Document’s current Selection is changed. This event cannot be canceled and will not bubble.

    The event can be handled by registering an event listener for selectionchange or by using the onselectionchange event handler.

    Syntax

    Use the event name in methods like addEventListener() or to set an event handler property.

    addEventListener("selectionchange",(event)=>{});onselectionchange=(event)=>{};

    Event type

    It is a generic Event.

    Example

    Here is the example of selectionchange event −

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Selection Change Example</title></head><body><h1>Text Selection Example</h1><p>Select some text in this paragraph to see the console messages about selection changes.</p><p>Try selecting different parts of this text to see how it updates!</p><script>
          // Using addEventListener to track selection changes
          document.addEventListener("selectionchange", () => {
             document.write("Selection has changed:", document.getSelection().toString());
          });
            
          // Using onselectionchange to handle selection changes
          document.onselectionchange = () => {
             document.write("Updated selection:", document.getSelection().toString());
          };
       </script></body></html>

    Output

    When you select any text in these paragraphs it will send messages to the console telling you that your selection has changed and displays the currently selected material.

    [Log] Selection has changed: - "" (example.html, line 16)
    [Log] Updated selection: - "" (example.html, line 21)
    [Log] Selection has changed: - "" (example.html, line 16)
    [Log] Updated selection: - "" (example.html, line 21)
    [Log] Selection has changed: - "" (example.html, line 16)
    [Log] Updated selection: - "" (example.html, line 21)
    [Log] Selection has changed: - "Selection" (example.html, line 16)
    [Log] Updated selection: - "Selection" (example.html, line 21)
    

    Node: selectstart event

    This event occurs when the user starts making a new selection. For example, they can click and drag to highlight text. Suppose the event has been canceled so the selection is not changed.

    Syntax

    Use the event name in methods such as addEventListener() or set an event handler property.

    addEventListener("selectstart",(event)=>{});onselectstart=(event)=>{};

    Event type

    It is also a generic Event.

    Example

    Here is the example of selectstart event −

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Select Start Example</title></head><body><h1>Text Selection Example</h1><p>Choose some text in this paragraph to check the console messages.</p><p>Try different parts of this text!</p><script>
          // Using addEventListener to track when text selection starts
          document.addEventListener("selectstart", () => {
             document.write("Selection started");
          });
          
          // Using onselectstart to handle when text selection starts
          document.onselectstart = () => {
             document.write("Selection started.");
          };
       </script></body></html>

    Output

    When you choose any text in these paragraphs, it will display “Selection started” and “Selection started.” on the terminal.

    [Log] Selection started (example.html, line 16)
    [Log] Selection started. (example.html, line 21)
    [Log] Selection started (example.html, line 16)
    [Log] Selection started. (example.html, line 21)
    [Log] Selection started (example.html, line 16)
    [Log] Selection started. (example.html, line 21)
    [Log] Selection started (example.html, line 16)
    [Log] Selection started. (example.html, line 21)
    [Log] Selection started (example.html, line 16)
    [Log] Selection started. (example.html, line 21)
  • JavaScript – Require() Function

    Files with JavaScript code that performs a specific task are called modules. It is easy to add, remove, and update functionalities without affecting your entire code because modules are self-contained and separated from other parts of code.

    If these modules are in separate JavaScript files you should use them inside the original JavaScript code.

    In this chapter we will cover what the require() function does, how it can be used and some differences between the require and import functions.

    How to Run ES and CommonJS Modules

    JavaScript module execution in the browser is dependent on import and export statements. The ES modules are loaded and exported by these statements, respectively. Most of online browsers support it by default and it is the accepted and official method for reusing modules in JavaScript.

    By default, Node.js supports the CommonJS module format which uses module.exports to export modules and require() to import them.

    JavaScript require() Function

    The require() method, a built-in CommonJS module function that Node.js supports, is how you add modules to your project. The reason for this is that by default, Node.js treats JavaScript code as CommonJS modules.

    The require() function accepts a string parameter that specifies the module’s path. This could be −

    • Core module: Node.js has various built-in modules. When the require() function receives a string parameter that does not begin with “./”, “../”, or “/”, it assumes it is a core module or a module installed in the node_modules folder.
    • Local Module: If the argument begins with “./” or “../”, Node.js treats it as a relative or absolute path and is trying to load the module from a file in that location.
    • Installed module: Node.js modules can also be installed via npm (Node Package Manager). In this case, Node.js searches for the module in the node_modules folder.

    Usage of require() Function

    The require() method is easy to use and understand because all you have to do is assign it to a variable. This function will accept the location name as an input. The following is the general syntax −

    const locName =require(locationName);

    Let us suppose you have a CommonJS module that exports the function *get_full_name*, as seen below −

    //utils.jsconstget_full_name=(first_name, last_name)=>{return`My full name is ${first_name} ${last_name}`;};
    module.exports = get_full_name;

    This module can then be used or included in your JavaScript file using the require() function −

    //index.jsconst get_full_name =require('./utils.js');
    console.log(get_full_name('Amit','Sharma'));

    The module is placed within a local file in the above code, so the local address is referred by the file name. But if you want to add an external module from the web you can use the web-based location −

    const myVar =require('http://web-module.location');

    Difference Between require() & import() Functions

    The require() and import() commands both provide code from external files into your JavaScript program, but they work differently. Here are the two main differences −

    • You can use the require() method throughout your code. You can even use it conditionally which means it will only run under certain conditions.
    • The import statement is always executed at the start of the file and cannot be used conditionally.
    • If you want to use require(), the file you are importing must have the .js extension.
    • If you are using an import, the file’s extension should be .mjs.

    The require() function is more flexible and can be used throughout your code, but import is more limiting, always starting at the beginning and frequently needing different file extensions.

  • JavaScript – Reactivity

    In web development responsiveness refers to how a system responds to changes in data. This concept is important for creating modern, dynamic web applications in which user actions need speedy responses like updating a page without reloading it or dynamically changing what the user sees when data is updated.

    This chapter covers some powerful JavaScript patterns that can help you build reactive systems. These patterns are commonly used in frameworks like React and Vue but understanding them in simple JavaScript allows you to understand the fundamental concepts.

    Why use Reactivity?

    Web apps today are highly interactive. When users click buttons, navigate pages or enter data so the application must reply quickly and change what shows on the screen. Addressing such updates manually can be difficult, but reactivity makes it easier by automatically responding to changes in data.

    Key Reactivity Patterns in JavaScript

    Now we will explore some key reactivity patterns in JavaScript in this section. These patterns allow us to react rapidly to changes in data and how the page responds to user actions. They are used in many popular libraries and frameworks but we will show how to use them in simple JavaScript.

    Pub/Sub: Simplified Data Flow Management

    The Pub/Sub (Publisher/Subscriber) pattern is a common approach to manage data flows. It differentiates between code that changes data (publisher) and code that responds to those updates (subscriber). This makes it easy to manage the various parts of an app separately.

    Example

    Following is the simple demonstration of this Reactivity Pattern −

    classPS{constructor(){this.t ={};// Tracks events and subscribers}sub(tp, cb){if(!this.t[tp]){this.t[tp]=[];}this.t[tp].push(cb);}pub(tp, d){if(this.t[tp]){this.t[tp].forEach((cb)=>cb(d));}}}const ps =newPS();
    ps.sub('n',(msg)=> console.log(`News: ${msg}`));
    ps.pub('n','New update available!');

    This method is used in systems like Redux in which components notice changes and update accordingly.

    Output

    This will generate the below result −

    News: New update available!
    

    Custom Events: Browser-Built Pub/Sub for Reactivity

    The browser provides an API for triggering and subscribing to custom events using the CustomEvent class and dispatchEvent method. The latter allows us to not only create an event, but also attach any needed data to it.

    Example

    Below is a simple example of this reactivity pattern −

    const evt =newCustomEvent('cEvt',{
      detail:'Event data',});const el = document.getElementById('target');
    el.addEventListener('cEvt',(e)=> console.log(`Event: ${e.detail}`));
    el.dispatchEvent(evt);

    This technique is appropriate for simple event triggering without the need of libraries.

    Output

    This will give the following outcome −

    Event: Event data
    

    Custom Event Targets

    If you do not wish to dispatch events globally on the window object, you can create your own event target.

    By modifying the native EventTarget class you can transmit events to a new instance. This makes sure your events are only triggered for the new class which prevents global propagation. Also you can connect handlers directly to this instance.

    Example

    The following code shows a simple use of this reactivity pattern −

    classCETextendsEventTarget{trig(evtName, evtData){const evt =newCustomEvent(evtName,{ detail: evtData });this.dispatchEvent(evt);}}const ct =newCET();
    ct.addEventListener('cEvt',(e)=> console.log(`Event: ${e.detail}`));
    ct.trig('cEvt','Hello from event!');

    Output

    This will create the below outcome −

    Event: Hello from event!
    

    Observer Pattern: Flexible Updates for Decoupled Code

    The Observer pattern is very similar to PubSub. You can subscribe to the Subject, which informs its subscribers (Observers) of changes and allows them to reply accordingly. This method is important for designing a disconnected and flexible architecture.

    Example

    Here’s a basic demonstration of how this reactivity pattern works −

    classSub{constructor(){this.obs =[];}sub(o){this.obs.push(o);}notify(d){this.obs.forEach((o)=> o.up(d));}}classObs{constructor(n){this.n = n;}up(d){
        console.log(`${this.n} got: ${d}`);}}const s =newSub();const o1 =newObs('Obs 1');
    s.sub(o1);
    s.notify('New info!');

    Output

    This will create the below outcome −

    Obs 1 got: New info!
    

    Reactive Properties with Proxy

    The Proxy object lets you intercept property access actions (get and set) within objects. This enables you to create reactivity and run code whenever a property’s value is retrieved or updated.

    Example

    This is a simple example showing the reactivity pattern in action −

    let d ={ n:'Akash', a:25};let rData =newProxy(d,{get(t, p){
        console.log(`Read: "${p}" = ${t[p]}`);return t[p];},set(t, p, v){
        console.log(`Changed: "${p}" from ${t[p]} to ${v}`);
        t[p]= v;returntrue;}});
    
    rData.n ='Vikas';

    Output

    This will lead to the following outcome −

    Changed: "n" from Akash to Vikas
    

    Individual Property Reactivity

    If you don’t need to keep track of all an object’s fields you can use Object.defineProperty to select one or Object.defineProperties to group them together.

    Example

    The code below provides a clear demonstration of this reactivity pattern −

    let u ={ _n:'Akash'};
    
    Object.defineProperty(u,'n',{get(){returnthis._n;},set(v){
        console.log(`Name changed from ${this._n} to ${v}`);this._n = v;}});
    
    u.n ='Vikas';

    Output

    This will produce the following result −

    Name changed from Akash to Vikas
    

    Reactive HTML Attributes with MutationObserver

    MutationObserver is a JavaScript API that monitors changes to the DOM (Document Object Model) like attribute changes, element additions or deletions etc. It is particularly applicable for running code in response to DOM changes without having to actively monitor them.

    Example

    Here is a simple implementation of this particular reactivity pattern −

    const el = document.getElementById('obs-el');const obs =newMutationObserver((muts)=>{
      muts.forEach(m=>{if(m.attributeName ==='class'){
          console.log('Class changed!');}});});
    
    obs.observe(el,{ attributes:true});

    Output

    This will generate the below result −

    Class changed!
    

    Reactive Scrolling with IntersectionObserver

    The IntersectionObserver API allows you to asynchronously monitor changes in the intersection of a target element with an ancestor element or the viewport of a top-level document. This means you can execute code anytime an element enters or quits the viewport or another specific element.

    This is particularly useful for lazy image loading, infinite scrolling, scroll position-based animations, and other features.

    Example

    Below is an example of this reactivity pattern −

    // Function to be called when the observed element is intersectingfunctiononIntersect(entries, obs){
      entries.forEach(e=>{
        e.target.style.backgroundColor = e.isIntersecting ?'lightgreen':'grey';});}// Create an IntersectionObserver with the callbackconst obs =newIntersectionObserver(onIntersect);// Start observing an elementconst el = document.getElementById('spec-el');
    obs.observe(el);

    Output

    Below is the output when the element enters the viewport −

    Element is now in view.
    

    This will be the output when the element exits the viewport −

    Element is now out of view.
  • JavaScript – Prototypal Inheritance

    Prototypal Inheritance

    The classical inheritance phenomenon involves making a new class that actually extends or reuses the attributes, functions, or methods of another class that are used by different programming languages (like C, C++, Java, and so on). JavaScript uses Prototype Inheritance rather than classical inheritance.

    Prototype Inheritance happens when one object uses the prototype linkage to access another object’s attributes or methods. All JavaScript objects derive properties and methods from their prototypes. Prototypes are hidden objects that inherit properties and methods from their parent classes.

    Syntax

    The prototype inheritance syntax contains the __proto__ property, which allows access to the child prototype. The syntax for prototype inheritance is as follows −

     child.__proto__ = parent;

    Example of Prototypal Inheritance

    Assume you have a basic car (a “prototype”) with basic parts like wheels and an engine. Now you want to create a certain vehicle, like a sports car, without beginning from scratch. Instead of creating a new vehicle, you use the existing one as a foundation (prototype). The sports vehicle inherits the basic car’s features (wheels and engine) but it can also be upgraded with optional features like more horsepower or a spoiler.

    It works the same way in JavaScript. An object can inherit characteristics and methods from another object (its prototype); still the inherited object can also be extended.

    Code for the Example

    In this case, sportsCar inherits the car’s characteristics and methods while also including a new feature called speed.

    // Basic car object (prototype)let car ={
       wheels:4,drive:function(){
         console.log("The car is driving");}};// SportsCar objectlet sportsCar ={
       speed:200,};// SportsCar object inherits from car object
     sportsCar.__proto__ = car; 
     
     console.log(sportsCar);// Calling method from car object using sportsCar
     sportsCar.drive();// Inherited from car
     console.log(sportsCar.wheels);// New property in sportsCar
     console.log(sportsCar.speed);

    Output

    Here is the outcome of the above code −

    The car is driving
    4
    200
    

    We can now use any method and property from the ‘car’ object to the ‘sportsCar’ object. Later in the chapter, we will talk about how an object’s characteristics and methods are inherited.

    Properties of Prototypal Inheritance

    Here are some of the properties of Prototypal inheritance is listed −

    • Properties are the characteristics that identify an object, such as its status or features.
    • In the case of prototypical inheritance, the prototype’s properties are shared by all instances that inherit from it.
    • When a property is accessed on an object, JavaScript searches for it first in the object and then in its prototype chain.
    • Properties can include data values, arrays, objects or other JavaScript data types.
    • Properties may be data values, arrays, objects, or any other JavaScript data type.

    Methods of Prototypal Inheritance

    Methods are functions that are bound to an object and can perform operations or computations on its data. Prototypical inheritance allows all instances that inherit from a prototype to share the methods provided in it. Methods can be invoked on an object, giving access to its attributes and other methods. It can execute a variety of tasks, such as modifying data, making calculations, and communicating with other objects or the environment.

    Now let us discuss some methods of prototypal inheritance in the below section −

    Object.create

    Object.create is a JavaScript method that generates a new object from the prototype and its properties. It enables you to create an object that inherits from a prototype without requiring a constructor method. This function is commonly used to initialize the prototype chain for objects, so it allows prototype-based inheritance.

    The syntax for Object.create is provided below −

     Object.create(proto,[propertiesObject]);

    Here,

    • – proto is the prototype object that the newly formed object will inherit from.
    • – propertiesObject (optional) is an object that defines additional properties for the newly created object. These properties are added to the newly created object and replace properties with the same name from the prototype chain.

    Example

    Here is an example for showing how to use Object.create method −

    // Create a prototype objectconst animalPrototype ={describe:function(){
        console.log(`This is a ${this.species}, and it is ${this.age} years old.`);}};// Create a new object that inherits from the animalPrototypeconst tiger = Object.create(animalPrototype);
    tiger.species ='Tiger';
    tiger.age =5;// Call the describe method on the tiger object
    tiger.describe();
    Output

    This will generate the below result −

    This is a Tiger, and it is 5 years old.
    

    Object.prototype.constructor

    The property Object.prototype.constructor denotes the function that produced the object instance. When an object is created with a constructor function or class, the constructor attribute is immediately set to the prototype.

    The constructor property is widely used to validate an object’s type and create new instances of the same type via JavaScript’s prototype-based inheritance.

    Example

    Here is an example of how to use Object.prototype.constructor −

    // Constructor function for creating Animal objectsfunctionAnimal(species, age){this.species = species;this.age = age;}// Creating an instance of the Animal objectconst animal =newAnimal('Tiger',5);// Accessing the constructor property of the prototype
    console.log(animal.constructor);
    Output

    This will produce the following result −

     Animal(species, age) { this.species = species; this.age = age; }
    

    hasOwnProperty

    In JavaScript the hasOwnProperty function is used to determine whether an object has a given property rather than inheriting it from its prototype chain. It returns a boolean value indicating whether the object contains the given property.

    The hasOwnProperty function is widely used in JavaScript to differentiate between an object’s own properties and those inherited from its prototype chain to make sure the property being checked exists directly on the object.

    Syntax

    The syntax for the hasOwnProperty is given below −

     object.hasOwnProperty(propertyName)

    Here,

    • object is an object to which the hasOwnProperty method is applied.
    • PropertyName is the name of the property to look for in the object.

    Example

    Below is an example of using the hasOwnProperty method −

    const animal ={
      species:'Lion',
      habitat:'Grasslands'};
    
    console.log(animal.hasOwnProperty('species')); 
    console.log(animal.hasOwnProperty('habitat')); 
    console.log(animal.hasOwnProperty('diet'));
    Output

    This will produce the following result −

    true
    true
    false
    

    The Prototype Chain

    The prototype chain is used to represent multiple inheritances at various hierarchy levels. We can connect one prototype to another using the steps mentioned below.

    Example

    Here’s an example of the prototype chain in JavaScript −

    let pupil ={
      id:1,};let fee ={
      id:2,};let institution ={
      id:3,};// Level 1 inheritance
    pupil.__proto__ = institution;// Level 2 inheritance
    pupil.__proto__.__proto__ = fee;// Outputs the pupil object's property
    console.log(pupil.id);// Outputs the institution object's property
    console.log(pupil.__proto__.id);

    Output

    Here is the output based on the hierarchy −

    1
    2
    

    Inheriting Methods

    Prototype inheritance inherits both the object’s properties and its methods. We can create a function in the parent class and call it from the child class. We can also include getter and setter methods in the parent class for usage by the child class.

    Example

    Here is the example for demonstrating how you can inherit methods −

    let userBase ={// Parent object
       canRead:true,
       profession:"",showReadPermission:function(){
         console.log(this.canRead);},// Setter method to set the profession of usersetinfo(value){this.profession = value;},// Getter method to get profession detailgetinfo(){return`${this.profession}`;},};let writer ={// Child object
       canWrite:true,};
    
    writer.__proto__ = userBase;// Calling parent function
    writer.showReadPermission();// Calling setter method
    writer.info ="blogger";// Calling getter method
    console.log(writer.info);

    Output

    This will produce the following result −

    true
    blogger
    

    Drawbacks of Prototypical Inheritance

    Here is the list of drawbacks you should consider while working with Prototypal inheritance −

    • It limits flexibility because a single __proto__ property can only inherit from one class.
    • Multiple inheritances can only happen at different levels. To inherit a second class we have to use the __proto__.__proto__ property, extending the hierarchy and making tracking more difficult.
    • Prototype relationships can only be created using objects.
    • Accessing elements with the same name as an element in the base class is difficult, that is, properties with the same name may exist in different classes, but they are difficult to access.
    • The same prototypes cannot be inherited since they create a loop.
  • JavaScript – Parse S-expressions

    The Lisp programming language family is built around S-expressions. In this article, you will learn about the steps of making a simple S-expression parser. This can form the basis for the Lisp parser.

    Lisp is the easiest language to implement and creating a parser is the first step. We can use a parser generator for this but it is easier to write the parser ourselves. We will use JavaScript.

    What are S-expressions?

    To define nested list data structures, we use s-expressions which are commonly used in Lisp and other functional programming languages. One s-expression can be either one atom or a sequence of s-expressions.

    If you do not know the Lisp language, S-expressions look like this −

    (+ (second (list "xxx" 10)) 20)
    

    This is a data format in which everything is made up of atoms or lists surrounded by parenthesis (atoms from other lists are separated by spaces).

    Like JSON, S-expressions can have a variety of data types. Numbers, strings, and symbols (without quotations) can represent variable names in several languages.

    In addition, you can use a specific dot operator to form a pair like the below.

    (1 . b)
    

    A list can be represented as doted pairs (which means that it is a linked list data structure).

    This is a list −

    (1 2 3 4)
    

    It can be written as −

    (1 . (2 . (3 . (4 . Nil))))
    

    The special symbol “nil” represents the conclusion of an empty list. This format allows you to generate any binary tree. However, we will not use this doted notation in our parser to avoid complicating things.

    What are the Uses of S-expressions?

    S-expressions are used for creating Lisp code, which can also be used to communicate data.

    They are also present in the textual version of WebAssembly. Probably because the parser is easy and you do not have to create your own format. Instead of JSON, use them to communicate between the server and the browser.

    Step-by-step S-expression Parser in JavaScript

    Here are the steps you need to follow for s-expression parser −

    • Tokenize the Input: First, divide the input string into tokens, which can be parenthesis (,) or symbols.
    • Recursive parsing: Tokens are processed recursively to create the structure. When it finds an opening parenthesis, it generates a new list. A closing parenthesis indicates the end of the current list.
    • Base Cases: Symbols (like integers or words) are returned as values but lists are created using expressions within parentheses.

    Example

    The following code converts the input string to readable tokens (symbols, integers, and parentheses). The parse() method loops over each token continuously. When it detects a (, it creates a new list. When it finds a ), it finishes the list. Numbers are parsed as JavaScript numbers; everything else is interpreted as a symbol (string).

    // Function to tokenize the input string into S-expression tokensfunctiontokenize(input){return input
          // Add spaces around '('    .replace(/\(/g,' ( ')// Add spaces around ')'.replace(/\)/g,' ) ').trim()// Split by whitespace.split(/\s+/);}// Recursive function to parse tokens into an S-expressionfunctionparse(tokens){if(tokens.length ===0){thrownewError("Unexpected end of input");}// Get the next tokenlet token = tokens.shift();// Start a new listif(token ==='('){let list =[];// Process until we reach a closing parenthesiswhile(tokens[0]!==')'){// Recursively parse the inner expressions  
            list.push(parse(tokens));}
          tokens.shift();// Remove the closing ')'return list;}elseif(token ===')'){thrownewError("Unexpected ')'");}else{// Return an atom (symbol or number) returnatom(token);}}// Function to identify if a token is a number or symbolfunctionatom(token){let number =Number(token);if(!isNaN(number)){// If it's a number, return it return number;}else{// Otherwise, return it as a symbol return token;}}// Usagelet input ="(+ 1 (* 2 3))";// Tokenize the inputlet tokens =tokenize(input);// Parse the tokens into an AST (Abstract Syntax Tree)let ast =parse(tokens);         
    
    console.log(ast);

    Output

    If you run the above code with the input, the output will be −

    ["+", 1, ["*", 2, 3]]