Category: Advanced Chapters

  • Functional Programming

    There are mainly two programming paradigms: The imperative programming paradigm and the declarative programming paradigm. Functional programming is a subtype of the declarative paradigm. The paradigm word refers to the approach to solving a particular problem.

    Functional programming has been in use for the last decades but came in the trend after 2015 when the last main revised version of JavaScript was released. There are many benefits to using functional programming, which we will discuss in this tutorial.

    Characteristics of Functional Programming

    Functional programming works as mathematical function works. It allows developers to develop software based on function evaluation. It means programmers can break the code into small parts, which we can call the function, making it easy to evaluate and test code. The following concepts of functional programming are covered in this tutorial

    • Pure Functions
    • Code Readability

    Pure Functions in JavaScript

    In JavaScript, we can write the pure function. In simple terms, a pure function takes the values as a parameter, performs some operations on that, and returns the output.

    The pure function never shares any variable with other function or use a global variable.

    The followings are the properties of a Pure function

    • A pure function always returns the same output for a given input.
    • A pure function does not depend on any external state or variables that are not passed to them as arguments.
    • A pure function does not produce any side effects, such as modifying global variables or changing the state of external objects.

    Now, let us see and understand the pure function with an example.

    Example

    In the example below, we have created the pure_func() named which takes the value as a parameter and multiplies it with 2. After that, it prints the value. Users can see that pure_func() is not sharing any variable globally with another function.

    Also, we can use the global_var directly without passing it as a parameter of a pure function. Still, we have passed it as a parameter as a pure function never shares any variable declared outside the function’s scope.

    <html><body><h2>Pure Function Example</h2><div id="result"></div><script>let result = document.getElementById('result');let global_var =10;functionpure_func(value){return value *2;}
    result.innerHTML =pure_func(5);</script></body></html>

    Immutability in JavaScript

    Immutability is another important concept of functional programming. In simple terms, immutability means that we cannot change the value of the variable once it is declared. In JavaScript, we can achieve immutability by using the const keyword. Lets see an example of immutability in JavaScript.

    Example

    In the example below, we have declared the variable using the const keyword. We have tried to change the value of the variable, which will throw an error as we cannot change the value of the variable declared using the const keyword.

    <html><body><h2>Immutability Example</h2><div id="result"></div><script>let result = document.getElementById('result');const value =10;
    value =20;
    result.innerHTML = value;</script></body></html>

    Ouptut

    Following is the output of the above code

    TypeError: Assignment to constant variable.
    

    When we run the above code, it will throw an error as we cannot change the value of the variable declared using the const keyword.

    Code Readability

    As we write all logic with functions in functional programming, it makes our code more readable. For example, in other programming languages we use for or while loops to iterate through the arrays. But functional programming allows us to use the for-of loop, which makes code more readable and tells other developers that we wanted to iterate through the array and perform some operation on every array element.

    Lets look at another example. Suppose we want to filter some values from the array. In other programming approaches, we write a manual function to filter values, but in the functional programming approach, we can use the filter() method, demonstrating that we want to filter values from the array based on the particular logic.

    Higher Order Functions

    The higher-order function allows us to pass the function as an argument of another function. For example, we can pass the callback function as an argument of the reduce() method of the array. In the callback function, we can write logic to reduce an array into a single element.

    Lets see an example of the higher-order function.

    Example

    In this example, we have used the reduce() method to reduce the array into a single element and passed the callback function as an argument. It represents the higher-order function as we have passed the function as an argument.

    <html><body><h2>Higher Order Function Example</h2><div id="result"></div><script>let result = document.getElementById('result');let arr =[1,2,3,4,5];let sum = arr.reduce((acc, val)=> acc + val);
    result.innerHTML = sum;</script></body></html>

    We have learned about the functional programming approach and how it is beneficial and different from the programming paradigm. We have learned that it provides a way to write maintainable and readable code with fewer bugs.

  • Form Handling

    We can handle forms in different ways like validating, submitting, altering, updating form data, etc. using JavaScript.

    Form Validation

    Form validation normally occurs at the server, after the client had entered all the necessary data and then pressed the Submit button.

    If the data entered by a client was incorrect or was simply missing, the server would have to send all the data back to the client and request that the form be resubmitted with correct information. This was really a lengthy process which used to put a lot of burden on the server.

    JavaScript provides a way to validate form’s data on the client’s computer before sending it to the web server. Form validation generally performs two functions.

    • Basic Validation First of all, the form must be checked to make sure all the mandatory fields are filled in. It would require just a loop through each field in the form and check for data.
    • Data Format Validation Secondly, the data that is entered must be checked for correct form and value. Your code must include appropriate checks to ensure that the data entered is the data you are expecting.

    Code snippet

    functionvalidateForm(){var x = document.forms["myForm"]["fname"].value;if(x ==""){alert("Name must be filled out");returnfalse;}}validateForm();

    In the above code, we have declared a function validateForm that checks if our form inputs are valid and input are properly fille, If not it will alert us to fill the missing data.

    Following is the output of the above code:

    Name must be filled out
    

    Form Submit

    After validating the form, we can submit the form data to the server. We can use methods like submit() and reset() to submit and reset the form data.

    Code snippet

    <form id="myForm" action="">
       First name:<input type="text" name="fname"><br>
       Last name:<input type="text" name="lname"><br><br><input type="button" value="Submit" onclick="myFunction()"></form><script>
    document.getElementById("myForm").submit();
    document.getElementById("myForm").reset();</script>

    In the above code, we have used the submit() method to submit the form data and reset() method to reset the form data.

    Conclusion

    We can handle forms easily in JavaScript. Validation becomes a lot more easier and faster with JavaScript. We can also submit and reset the form data using JavaScript.

  • Empty String Check

    String is a data type, which we can use to save the data present in text format. It is a sequence of characters inside the double or single quotes.

    Sometimes we need to check whether the string is empty or not. In JavaScript, we can check the empty string using the following methods.

    Using the length property

    It’s really simple and most common way to check the empty string. All we have to do is check the length of the string using the length property of the string. If the length of the string is 0, then it is an empty string. If length is 1 or more than 1 then string is not empty.

    Syntax

    Below is the syntax given to check the empty string using the length property.

    if(string_name.length ===0){// string is empty}

    Example

    Below is the example code given, that shows how to use the length property to check the empty string.

    <html><body><script>var str ='';if(str.length ===0){
       document.write('String is empty');}</script></body></html>

    Following is the output of the above program −

    String is empty
    

    Using the trim() method

    The string.trim() method allows us to remove the space from the start of the string. After moving the space, we can check that if the strings length is zero, the string can be either empty, null, or undefined.

    Syntax

    Below is the syntax given to check the empty string using the trim() method.

    if(string_name.trim()===''){// string is empty}

    Example

    Below is the example code given, that shows how to use the trim() method to check the empty string.

    <html><body><script>var str =' ';if(str.trim()===''){
       document.write('String is empty');}</script></body></html>

    Following is the output of the above program −

    String is empty
    

    So, we have seen how to check the empty string in JavaScript using the length property and trim() method.

  • Higher Order Function

    A higher order function accepts other functions as parameters and returns a function. To know about Higher-order functions, we should learn about call back functions.

    A call back function is a function that is passed to another function as an argument. With the help of call back functions, one function can call another function and the call back function runs only after other function has finished. Some of the higher-order functions are map, reduce and filter.

    Let us take an example and implement it without using any higher order functions.

    Example

    In the following code, we have a list of numbers and we want to increment each element by 10, to achieve this without using higher order functions, we need to loop through the array using for loop and increment each value by 10 and push the incremented values to a new array. Finally, print the incremented array using console.log().

    const numbers =[1,2,3,4,5];
    incrementedNums=[]for(i =0; i < numbers.length; i++){
       added = i +10
       incrementedNums.push(added)}
    console.log(incrementedNums)

    Output

    [ 11, 12, 13, 14, 15 ]
    

    And this is how a map function works. It iterates over an array and executes a provided function once for each array element and return the output as an array. Map() function does not change the original array, also it does not perform the operation on an empty array.

    Below JavaScript functions are some inbuilt Higher Order Functions

    • map()
    • filter()
    • reduce()
    • forEach()

    Advantages of Higher Order Functions

    Following are the advantages of Higher Order Functions −

    • Code Reusability
    • Less Code
    • Easy to Understand
    • Easy to Maintain

    Usage of Higer Order Function

    Let us take the same example and implement it using higher order functions.

    Using map() function

    map() function iterates through an array and appllies a callback functionfor every element in the array. Let us consider another example and understand. In the following example, map function iterates through the given array of numbers and passes them into sqrt function, resulting an output of root values.

    numbers=[4,9,16,25,36]
    root= numbers.map(Math.sqrt)
    console.log(root)

    Output

    [2, 3, 4, 5, 6]
    

    Using filter() function

    The filter() method shallow copies of the array and filters down the value which passes the condition implemented by the provided callback function. It is an iterative method, which calls the callback function given as an argument for each element in the array and return an output array with the elements which returned truthy value by the callback function.

    Example

    In the following example, we have a list of numbers and we want to filter out the even numbers from the list. To achieve this, we need to use filter() function and pass a callback function which returns true if the number is even.

    numbers=[10,11,12,14,15]
    
    even=numbers.filter(iseven)functioniseven(n){return(n%2===0)}
    console.log(even)

    Output

    [ 10, 12, 14 ]
    

    Using reduce() function

    Similar to map and foreachreduce method also executes a callback function (reducer function) on every element of the array, resulting a single output. In simple terms, the reduce method reduces the array to a single value. The Parameter of the reducer function is a callback function, which further has two arguments, accumulator and current value. Where current value is the current iterated value of the array. accumulator accumulates the callback function’s output. The final return value is stored in the accumulator.

    Example

    In the following example, we have a list of numbers and we want to find the sum of all the numbers in the list. To achieve this, we need to use reduce() function and pass a callback function which returns the sum of two numbers.

    numbers=[10,11,12,13]
    
    total =numbers.reduce(function(acc,el){return acc+el
    },0)
    
    console.log(total)

    Output

    46
    

    Using forEach() function

    The forEach method is similar to a map function, where it executes the callback function for each element in the array. The only difference between forEach() and map() is that, map function returns an array output, where as forEach returs undefined, it just iterates through the array.

    Example

    Below code shows the working of forEach method

    const numbers =[10,20,30,40];
    
    sum=0
    numbers.forEach(add)functionadd(n){
       sum=sum+n
    }
    console.log(sum)

    Output

    100
    

    Conclusion

    Higher Order Functions operate on other functions, either by taking them as arguments or by returning them. JavaScript being a functional programming language, supports Higher Order Functions. Higher Order Functions are used to make the code more readable and maintainable. They help in reducing the code and make it more concise. JavaScript provides inbuilt Higher Order Functions like map(), filter(), reduce() and forEach().

  • Graph Algorithms

    A graph is a data structure which consist nodes and edges. The node are simply vertices and the lines which connect them are edges. Graph is non-linear data structure.

    A Graph algorithms in JavaScript are used to solve the graph problems. These algorithms are used to traverse the graph, find the shortest path, etc. We can use these algorithms to solve the problems like finding the shortest path, finding the connected components, etc.

    Types of Graph

    Before dwelling deep into this chapter let’s learn about types of graphs.

    • Directed Graph : Directed graph is a graph in which the edges have a direction. In other word, we can call it a Digraph. These edges may be one way or two ways and also it may have loops. Arrow is used for representing the direction of the edges.
    • Undirected Graph: Undirected graph are exactly opposite of directed graph. Means, in this graph edges does not have any direction. We can also call it simple graph.
    • Weighted Graph: Weighted graph means the graph edges have some weight it means value. It help us to define the cost, distance, etc. between the vertices.
    • Unweighted Graph: Unweighted graph is opposite of weighted graph. It means the graph edges does not have any weight at all.

    Graph Representation

    There are two ways to represent the graph:

    • Adjacency Matrix: In this representation, we use a 2D array to represent the graph. The elements of the array are 0 or 1. If there is an edge between two vertices then we put 1 otherwise 0.
    • Adjacency List: In this representation, we use an array of linked list to represent the graph. Each element of the array represents a vertex and the linked list represents the edges of that vertex.

    Graph Algorithms

    When we talk about graph algorithms, there are plenty of the algorithms available. We mostly use these algorithms to solve the graph problems. We have listed some of them below:

    • Breadth First Search (BFS)
    • Depth First Search (DFS)
    • Topological Sorting

    Breadth First Search (BFS) Algorithm

    This algorithm we can use for traversing the graph. It is very useful for resolving many problems. In this algorithm, we start our traversal from the root node and then we go one level down, traverse all the nodes at that level and then move to the next level. We use queue data structure to implement this algorithm.

    Algorithm

    We can implement the BFS using the below steps given:

    • First, we need to create a queue and add the root node to the queue.
    • Then we will create a visited array and mark the root node as visited.
    • Then loop through the queue until it is empty.
    • Then we will dequeue the node from the queue and print it.
    • After that, get all the adjacent nodes of the dequeued node and if they are not visited then mark them as visited and enqueue them.
    • Repeat the above steps until the queue is empty.

    Implementation

    Following is the implementation of BFS algorithm in JavaScript:

    functionBFS(graph, root){let visited =[];let queue =[];
       queue.push(root);while(queue.length >0){let node = queue.shift();if(!visited[node]){
    
         console.log(node);// Process the node
         visited[node]=true;}// Ensure neighbours is definedconst neighbours = graph[node]||[];for(let i =0; i &lt; neighbours.length; i++){let neighbour = neighbours[i];if(!visited[neighbour]){
            queue.push(neighbour);}}}}let graph =[[1,2],[3,4],[5],[6],[6],[7],[8],[]];BFS(graph,0);</pre>

    Following is the output of the above program −

    Following is the output of above code

    0
    2
    5
    7
    1
    4
    6
    8
    3
    

    Depth First Search (DFS) Algorithm

    Similar to BFS, this algorithm is also used for traversing the graph but in different way. In this algorithm, we start from the root node then move to left child or right child go to in-depth until we reach to leaf node then we backtrack and move to the next child.

    Algorithm

    We can implement the DFS using the below steps given:

    • First, we need to create a stack and add the root node to the stack.
    • Then we will create a visited array and mark the root node as visited.
    • Then loop through the stack until it is empty.
    • Then we will pop the node from the stack and print it.
    • After that, get all the adjacent nodes of the popped node and if they are not visited then mark them as visited and push them to the stack.
    • Repeat the above steps until the stack is empty.

    Implementation

    Following is the implementation of DFS algorithm in JavaScript:

    functionDFS(graph, root){let visited =[];let stack =[];
       stack.push(root);while(stack.length >0){let node = stack.pop();if(!visited[node]){
    
         console.log(node);
         visited[node]=true;}// Set a default value if graph[node] is undefinedconst neighbours = graph[node]||[];for(let i =0; i &lt; neighbours.length; i++){let neighbour = neighbours[i];if(!visited[neighbour]){
            stack.push(neighbour);}}}}let graph =[[1,2],[3,4],[5],[6],[6],[7],[8],[]];DFS(graph,0);</pre>

    Output

    Following is the output of above code

    0
    2
    5
    7
    1
    4
    6
    8
    

    Topological Sorting Algorithm

    Using this algorithm we can actually sort the vertices of the graph in such a way that for every edge from vertex u to vertex v, u comes before v in the ordering.

    Algorithm

    We can implement the Topological Sorting using the below steps given:

    • We will create a visited array and mark all the vertices as not visited.
    • Then, we will create a stack to store the vertices.
    • Then we will loop through all the vertices and call the recursive function.
    • Then we will create a recursive function and mark the current node as visited.
    • Then we will loop through all the adjacent nodes of the current node and if they are not visited then call the recursive function.
    • Then push the current node to the stack.
    • Repeat the above steps until all the vertices are visited.
    • Finally, print the stack.

    Implementation

    Following is the implementation of Topological Sorting algorithm in JavaScript:

    functiontopologicalSort(graph){let visited =[];let stack =[];for(let i =0; i < graph.length; i++){if(!visited[i]){topologicalSortUtil(graph, i, visited, stack);}}while(stack.length >0){
    
      console.log(stack.pop());}}functiontopologicalSortUtil(graph, node, visited, stack){
    visited[node]=true;const neighbours = graph[node]||[];for(let i =0; i < neighbours.length; i++){let neighbour = neighbours[i];if(!visited[neighbour]){topologicalSortUtil(graph, neighbour, visited, stack);}} stack.push(node);}// Valid DAGlet graph =[[1,2],// Node 0 -> 1, 2[3],// Node 1 -> 3[3,4],// Node 2 -> 3, 4[],// Node 3 -> No outgoing edges[5],// Node 4 -> 5[]// Node 5 -> No outgoing edges];topologicalSort(graph);

    Output

    Following is the output of above code

    0
    1
    2
    3
    4
    5
    6
    7
    8
  • Get the Current URL

    In JavaScript, we can get the current URL of the page using the window.location object. The window.location object contains information about the current URL of the page.

    We can get URL from another method also, which is document.URL. Another method is document.documentURI which returns the location of the document as a string.

    Using window.location

    The window.location object can be used to get the current URL. The window.location.href property returns the href (URL) of the current page. We can also use window.location or location in place of window.location.href.

    Example

    In this example we will use window.location.href to get the current URL. In below example you can try using window.location or location in place of window.location.href.

    <html><body><p id="demo"></p><script>let currentURL = window.location.href;
       document.getElementById("demo").innerHTML = currentURL;</script></body></html>

    Output

    We execute the code online. When you run the above code, You will able to see console message with the current URL.

    Using document.URL

    We could also use document.documentURI and document.URL properties. The document.URL returns the URL of the document as a string.

    Example

    In this example, we will use the document.URL to get the current URL of the document.

    <html><body><p id="demo"></p><script>let currentURL = document.URL;
       document.getElementById("demo").innerHTML = currentURL;</script></body></html>

    Output

    When you execute the above code, In console the current URL will be displayed.

    Using document.documentURI

    The document.documentURI returns the location of the document as a string.

    Example

    In this example, we will use the document.documentURI to get the current URL of the document.

    <html><body><p id="demo"></p><script>let currentURL = document.documentURI;
       document.getElementById("demo").innerHTML = currentURL;</script></body></html>

    Output

    When you execute the above code, In console you will be able to see the current URL of the document.

  • Null Checking

    In this chapter, we will learn how to check the null values in JavaScript. The null value indicates the intentional absence of any object value. It is a JavaScript primitive value that is false when used in Boolean operations.

    This distinguishes null from the related primitive value undefined, which is an unintended absence of any object value. This is because a variable that has been declared but not given a value is undefined rather than null.

    We can take an example of a box that has nothing in it, nothing at all. We can say that the box is null. Similarly, in JavaScript, we can say that a variable is null when it has no value.

    Checking Null Values

    We can check the null values in javascript using quite a few methods. Let’s see them one by one.

    • Using the Strict equality operator (===)
    • Using the typeof operator
    • Using Object.js method

    Using the Strict equality operator (===)

    In this method, we will see how we can check null values using the strict equality operator (===). The strict equality operator compares two values for equality. It returns true if the values are equal and false otherwise. It is a strict equality operator, which means it checks both the type and the value of the variable.

    Syntax

    The syntax for checking null values using the strict equality operator is given below.

    let result =( v ===null);

    Example

    Below is the example of checking null values in JavaScript.

    <!DOCTYPE html><html><head><title>Check fornull values in JavaScript</title></head><body><h2>Check fornull values using the strict equality operator.</h2><div id="output"></div><script>let output = document.getElementById("output");var v =null;if(v ===null){
       output.innerHTML ="Value is null";}else{
       output.innerHTML ="Value is not null";}</script></body></html>

    In the above output, the variable is being checked for null and the value is being executed in the if-block that the variable contains a null value.

    Using the typeof operator

    The typeof operator may be used to determine the data type of a JavaScript variable. Here we use the typeof operator with the null operator. The (!variable) means the value is not null and if it is checked with the typeof operator variable which has the data type of an object then the value is null.

    Syntax

    Following is the syntax to typeof operator

    typeofvar;

    Here var is the variable whose data type is to be checked and is used as a parameter.

    Example

    In this example, we use the JavaScript typeof operator to check whether the values of a given variable are equal to null or not.

    <!DOCTYPE html><html><head><title>Check fornull values in JavaScript</title></head><body><h2>Check fornull values using the typeof operator.</h2><div id="output"></div><script>let output = document.getElementById("output");var v =null;if(!v &&typeof v ==="object"){
       output.innerHTML ="Value is null";}else{
       output.innerHTML ="Value is not null";}</script></body></html>

    The variable is tested for null in the above output, and the value is executed in the if-block that the variable has a null value.

    Using Object.js method

    The Object.is() function in JavaScript that compares two values to see whether they are the same. A boolean value indicates if the two parameters in the function have the same value. Two values could be the same if both the values are null.

    Syntax

    Following is the syntax to Object.is() method

    Object.is( q,null);

    Parameters

    The parameters used in the Object.is() method are as follows

    • q The first value to compare.
    • null The second value to compare.

    Example

    In the program below, we use the Object.is() function to check for null values

    <!DOCTYPE html><html><head><title>Check fornull values in JavaScript</title></head><body><h2>Check fornull values using the Object.is() method.</h2><div id="output"></div><script>let output = document.getElementById("output");var v =null;if(Object.is(v,null)){
       output.innerHTML ="Value is null";}else{
       output.innerHTML ="Value is not null";}</script></body></html>

    Output

    Following is the output of the above program.

    Value is null
    

    In the above output, the variable is being checked for null and the value is being printed with a true statement that the variable contains a null value.

    Conclusion

    In this chapter, we have learned how to check null values in JavaScript using the strict equality operator, typeof operator, and Object.is() method. We have also seen the syntax and examples of each method.

  • Nested Loop

    In JavaScript, a loop inside another loop is called a nested loop. We need nested loop when we iterate over multi-dimension array or matrix. When we have to perform repeated actions on each element of an array we do use nested array.

    Nested loops in JavaScript

    Let’s say we have two arrays, one is an array of rows and another is an array of columns. We can use nested loop to iterate over each element of the array of rows and then iterate over each element of the array of columns.

    Syntax of Nested Loop

    Below is the syntax of nested loop in JavaScript.

    for(let i =0; i < rows.length; i++){for(let j =0; j < columns.length; j++){// code block to be executed}}

    Nested Loop Using for Loop

    In the following code snippet that demonstrates how we can use nested for loops.

    let rows =[1,2,3];let columns =[4,5,6];for(let i =0; i < rows.length; i++){for(let j =0; j < columns.length; j++){
    
      console.log(rows[i]+" "+ columns[j]);}}</pre>

    Output

    1 4
    1 5
    1 6
    2 4
    2 5
    2 6
    3 4
    3 5
    3 6
    

    We have two arrays, one is an array of rows and another is an array of columns. We are using nested loop to iterate over each element of the array of rows and then iterate over each element of the array of columns.

    Nested Loop Using while Loop

    We can use while loop same as for loop to iterate through the array elements. Below is the code snippet that shows how we can use nested while loops.

    let rows =[1,2,3];let columns =[4,5,6];let i =0;while(i < rows.length){let j =0;while(j < columns.length){
    
      console.log(rows[i]+" "+ columns[j]);
      j++;}
    i++;}

    Output

    1 4
    1 5
    1 6
    2 4
    2 5
    2 6
    3 4
    3 5
    3 6
    

    We have two arrays, one is an array of rows and another is an array of columns. We are using nested loop to iterate over each element of the array of rows and then iterate over each element of the array of columns.

  • Linked List

    Linked List is an ordered collection of data elements. In linked list the data will be represented in Nodes. Node has two parts, the first part will be holding the data of the element and second part of the node (pointer) will store the address of the very next node. In linked list elements are stored in a sequential manner.

    Node: This represents each element in the linked list. It consists of 2 parts, data and next.

    Head: The reference to the first element is called a head.

    Next: This is the pointer that points to the next node in the linked list.

    Linked List

    Types of Linked List

    There are three types of linked list:

    • Singly Linked List: In this type of linked list, each node in the list is connected only to the next node in the list.
    • Doubly Linked List: In this type of linked list, each node in the list is connected to the next and the previous node.
    • Circular Linked List: In this type of linked list, the last node is connected to the first node.

    Implementations of Linked List

    Defining node class and liked list class, this is basically the prerequisite in order to implement a linked list in JavaScript. In this step, 2 classes namely one for the nodes and the other for the linked list need to be created.

    The Node class represents a single node in the linked list. It has two properties which are data and next. The data property is used to store the actual data of the node, whereas the next property is a reference to the next node in the list. The Node class consists of a constructor that initializes the data and next property when creating a new Node.

    classNode{constructor(data){this.data = data;this.next =null;}}

    The LinkedList class is a representation of the linked list itself. It has a head property that refers to the first node in the list. The LinkedList class also has a constructor that initializes the head property when creating a new LinkedList.

    classLinkedList{constructor(){this.head =null;this.tail =null;this.length =0;}}

    The LinkedList class also consists of a method that allows you to insert, delete, and search for nodes in the list while simultaneously allowing other operations like printing the list, counting the elements, reversing the list and so on.

    Inserting a Node

    To insert a node in the linked list, we need to create a new node first and need to assign the data to it. Then we need to check if the head is null, if it is null then we need to assign the new node to the head. If the head is not null, then we need to traverse the list till the last node and assign the new node to the next of the last node.

    insert(data){let node =newNode(data);if(!this.head){this.head = node;this.tail =this.head;}else{this.tail.next = node;this.tail = node;}this.length++;returnthis;}

    Searching a Node

    If there is a need to search a element in the linked list we can simply traverse the linked list and check if current node data is equal to the data we are searching for. If we find the data we are searching for, we can return the node.

    search(data){let current =this.head;while(current){if(current.data === data){return current;}
    
      current = current.next;}returnnull;}</pre>

    Deleting a Node

    If we want to delete a node from the linked list, let's say you have node prev and node current and you want to delete the node current . You can simply assign the next of the prev to the next of the current and the node current will be deleted.

    delete(data){if(!this.head)returnnull;if(this.head.data === data){this.head =this.head.next;this.length--;returnthis;}let current =this.head;let prev =null;while(current){if(current.data === data){
    
         prev.next = current.next;this.length--;returnthis;}
      prev = current;
      current = current.next;}returnnull;}</pre>

    Printing the Linked List

    You can print the elements of a linked list by traversing through the list and printing the data of each node.

    print(){let current =this.head;while(current){
    
      console.log(current.data);
      current = current.next;}}</pre>

    Code Example

    Following is an example of a linked list implementation in JavaScript.

    <!DOCTYPE html><head><title>Linked List</title></head><body><p id ="demo"></p><script>classNode{constructor(data){this.data = data;this.next =null;}}classLinkedList{constructor(){this.head =null;this.tail =null;this.length =0;}insert(data){let node =newNode(data);if(!this.head){this.head = node;this.tail =this.head;}else{this.tail.next = node;this.tail = node;}this.length++;returnthis;}search(data){let current =this.head;while(current){if(current.data === data){return current;}
    
         current = current.next;}returnnull;}delete(data){if(!this.head)returnnull;if(this.head.data === data){this.head =this.head.next;this.length--;returnthis;}let current =this.head;let previous =null;while(current){if(current.data === data){
            previous.next = current.next;this.length--;returnthis;}
         previous = current;
         current = current.next;}returnnull;}print(){let current =this.head;let output ="";while(current){
          output += current.data +" ";
          current = current.next;}
      document.getElementById("demo").innerHTML = output;}}let list =newLinkedList();
    list.insert(1); list.insert(2); list.insert(3); list.insert(4); list.insert(5); list.print();</script></body></html>

    Output

    Following is the output of the above code.

    1 2 3 4 5
    

    In the above example, we have created a linked list with elements 1, 2, 3, 4, and 5. We have inserted these elements into the linked list and printed the list.

  • Lazy Loading

    In JavaScript, there is way to make website faster. Means, we can only load what we need first like images, videos,etc. The file or data which is not needed at the moment that can be loaded later when it needed this is called lazy loading.

    For example, When you open the Instagram app, It only loads the images and videos you are able to see on current screen frame. But when you scroll down, you will see more images and videos are loading. Instagram uses lazy loading for making better user experience and faster loading of the app.

    Why do we need Lazy Loading

    Following are the uses of lazy loading:

    • Lazy loading is useful when you have a lot of images and files on your website.
    • Lazy loading is also useful for improving the performance of the website.
    • Lazy loading is also used for improving the user experience.
    • Lazy loading is also used for reducing the loading time of the website.

    Example of Lazy Loading

    Following is the code snippet for lazy loading in JavaScript:

    const images = document.querySelectorAll("[data-src]");functionpreloadImage(img){const src = img.getAttribute("data-src");if(!src){return;}
       img.src = src;
       img.removeAttribute("data-src");}const imgOptions ={
       threshold:0,
       rootMargin:"0px 0px 300px 0px"};const imgObserver =newIntersectionObserver((entries, imgObserver)=>{
       entries.forEach(entry=>{if(!entry.isIntersecting){return;}else{preloadImage(entry.target);
    
         imgObserver.unobserve(entry.target);}});}, imgOptions);
    images.forEach(image=>{
    imgObserver.observe(image);});</pre>

    This code snippet is all about making images load when they are in the viewport. It finds images with the attribute data-src (it is like a placeholder) and it sets up a "watcher" for each image.

    The watcher(IntersectionObserver) will check if the image is in the viewport and if it found that it is, it will load the actual image and remove the data-src attribute. Then it will stop watching that image so it doesn't laod again. This way page dosen't load everything at once.