Skip to content

Rahul12Arora/Javascript_Theory_Notes_RA

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 

Repository files navigation

Javascript_Theory_Notes

Javascript_Theory 140322

Scope & Var, let & const

A scope of a parameter is a certain region of a programm or its bound where it can be access or recognised

Scope types

1.) Global scope
2.) Function Scope
3.) Block Scope

var is function scoped but let & const are block scoped

In JavaScript, the global scope is the outermost scope, outside of any functions or blocks. Any variables or functions declared in the global scope are accessible from anywhere in the code, including within functions or blocks.

Shadowing

Shadowing is when an inner variable is prioritized over an outer variable of the same name, when in use inside the inner variable's scope

function test(){
    var a = "hello"
    let b = "goodbye"
    
    if(true){
        let a = "hi"    // Shadowing
        var b = "bye"   // Illegal shadowing
    }
}

Declaration

let & const cannot be re declared in the same scope var can be redeclared in the same scope

const cannot be declared without initialization, once initialized it cannot be re-initialized

Hoisting

An execution context is created

** Variables & definitions are moved to the top during the creation phase before executing even a single line of code**

Creation Phase

  • Creates a Global/Window Object
    • It creates a memory heap for storing variables & function references
    • It initializes memory variables as undefined & function definitions with their entire definition
  • Creates an Execution Phase
    • Javascript code is executed line by line
    • For Every function a new execution context is created
    Note - let and const are hoisted in script memory & they are in temporal dead zone until they are initialized.
    Temporal dead zone is the time between declaration and initialization of a variable
    

    Call stack is used to keep track of all the function calls

    Map, filter & reduce

    Map

    const arr = [1,2,3,4];
    
    const newarr = arr.map((item,index,array)=>{
        return item*10;
    })
    

    Filter

    const arr = [1,2,3,4];
    
    const grtrthan2 = arr.filter((item,index,array)=>{
        return item>2;    //returns items whose callback functions return true
    })
    

    Reduce

    const arr = [1,2,3,4];
    
    const sum = arr.reduce((accumulator,item,index,array)=>{
        return accumulator+item;
    },0)   //if we dont provide the initial value for accumulator it takes the value of first element by default & starts the iteration from second element
    

    Polyfills for map, filter & reduce

    When we use the map function we define the callback function that dictates/returns the value to be added in the new array

    map

    Array.prototype.myMap = function(cb){
        let newarr = [];
        
        for(let i=0;i<this.length;i++){
            newarr.push(cb(this[i],i,this))
        }
        return newarr;
    }
    

    filter

    Array.prototype.myFilter = function(cb){
        let newarr = [];
        
        for(let i=0;i<this.length;i++){
            if(cb(this[i],i,this)) newarr.push(this[i]);
        }
        return newarr;
    }
    

    reduce

    Array.prototype.myReduce = function(cb,initialValue){
        let accumulator = initialValue;
        
        for(let i=0;i<this.length;i++){
           if(accumulator){
           accumulator = cb(accumulator,this[i],i,this)
           }
           else{
           accumulator = this[i]
           }
        }
        return acuumulator;
    }
    

    map v/s forEach

    ** forEach lets us iterate through the array, doesn't return anything **

    const avengers = ['thor', 'captain america', 'hulk'];
    avengers.forEach((item, index)=>{
    	console.log(index, item)
    })
    

    looping with for, forEach, for in & for of

    https://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript.html
    

    Functions

    Function declaration/definition/statement

    **Normal function**
    function square(num){
    	return num*num;
    }
    

    Function Expression

    When you store function inside a variable

    const square = function(num){
    	return num*num;
    }
    

    RHS of above; i.e a function without a name is known as an anonymous function, can be assigned to a variable or passed as a callback function

    First Class Function

    First class function are those that can be treated as variables i.e they can be passed & returned from other functions

    function square(num){
    	return num*num;
    }
    function displaySquare(fn){
    	console.log("square is" + fn(5));
    }
    displaySquare(square);
    

    IIFE

    Immediately invoked Function Expressions: functions that are invoked just after writing them

    (function square(num){
    	console.log(num*num);
    })(5);
    

    Reminder - var is function scope, let & const are block scope Eg:

    for(var i=0;i<5;i++){
        setTimeout(function(){
            console.log("i is passed in console as ",i);
        },i*1000)
    }
    output = 5 5 5 5 5
    
    for(let i=0;i<5;i++){
        setTimeout(function(){
            console.log("i is passed in console as ",i);
        },i*1000)
    }
    
    output = 0 1 2 3 4
    

    Reminder - Functions are hoisted completely with definition at top

    Paramters vs Arguments

    ** Arguments are values passed to a function** ** Paramters are the variables that recieve those values in the function definition**

    ... Spread & Rest operator

    Spread - Distributes the variables from an array or object

    nums = [1,2,3,4]
    function mutiply(a,b,c,d){
    	//function body
    }
    function multiply(...nums)
    

    Rest - Collects multiple variables passed as arguments & presents them as an array to us

    func(a, b, ...nums)

    Callback function

    Callback function is a function that is passed as an argument to another function, which is then invoked inside the outer function

    The function that recieves a callback function as an argument is called a Higher order function

    Functions in js are first class members, they csn be treated as variables

    Arrow Functions

    const arrowfunction = (num1,num2) => {
    	return num1+num2
    }
    

    Arguments

    const square = function(){
    	console.log(arguments);
    }
    
    square(1,2,3,4,5)     // arguments will give us all the arguments, This arguments keyword is not available in arrow functions
    

    This keyword

    let user = {
    	username:"rahul"
    	rc1: () => { console.log(this.username) }       //this keyword points to global object
    	rc2: function() { console.log(this.username) }  // this keyword points to object that this function is a part of
    }
    

    Closures

    Everytime a function is defined, a closure is formed with it

    A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.
    Lexical Scope allows inner functions to access the scope of their outer functions. const and let are block scoped variables.


    Scope determines the accessibility of variables, objects, and functions from different parts of the code.

    Closure Scope chain - a closure has access to local, parent's & global scope when it is nested (we already know that)

    Eg-1
    var name = "Global scope"
    
    function outer(){
        var name = "inside function scope"
        return function inner(){
            console.log(name);
        }
    }
    
    const newfunc = outer();
    newfunc();   // output => inside function scope
    // newfunc() knows the value of variable "name" because along with the function definition, it also carries it's lexical enviornment i.e it's a closure.
    
    Eg-2
    
    function createBase(num)
    {
        return function addsix(innernum){
            return num+innernum;
        }
    }
    
    const addsix = createBase(6);
    console.log(addsix(10)); //16
    console.log(addsix(20)); //26
    

    Important - How to run a loop with var without referencing to the same value in an asynchronous function

    for(var i=0;i<10;i++){
    
        (function(passed){setTimeout(function(){
            console.log(passed);
        }, i*1000)})(i);
    }
    //we took advantage by forming a closure of every iteration of i that is passed by wrapping asynchronous function in a wrapper function that takes current value of i & forms a closure with it
    
    Important question
    
    function fun(){
        var _counter = 0;
    
        function add(val){
            _counter+=val;
        }
        function retrieve(){
            return _counter;
        }
    
        return {
            add,
            retrieve
        }
    
    }
    
    const c1 = fun();
    c1.add(10)
    console.log(c1.retrieve());
    

    Ques. What is Module Pattern?

    Hiding private functions & allowing public functions to be accessible from inside a fucntion

    function modulePattern(){
        function privatefunction(){
            console.log("I am private");
        }
        
        return {
            publicfunction : function publicfunction(){
                console.log("I am public");
            },
            publicfunction2 : function publicfunction2(){
                console.log("I am public2");
            }
        }
    }
    
    modulePattern().privatefunction();    //unsupported syntax, Hence protected
    modulePattern().publicfunction();     //I am public
    modulePattern().publicfunction2();    //I am public2
    

    once(fun) & memoize(fun)

    Currying

    In currying a function takes one argument at a time & returns another function expecting the next argument f(a,b) is converted to f(a)(b) with currying
    function normal(a,b){
        console.log(a,b);
    }
    normal(1,2)
    
    // converting into curried function
    function f(a){
        return function (b){
            console.log(a,b);
        }
    }
    
    f(3)(4)
    

    Ques - Why should currying be used? Following are the reasons why currying is good :

    ✅ It makes a function pure which makes it expose to less errors and side effects.

    ✅ It helps in avoiding the same variable again and again.

    ✅ It is a checking method that checks if you have all the things before you proceed.

    ✅ It divides one function into multiple functions so that one handles one set of responsibility.

    function evaluate(operation) {
        return (a) => {
            return (b) => {
            if(operation === "sum")
                      return a + b;
                        else if(operation === "multiply")
                        return a * b;
                        else if(operation === "divide")
                        return a / b;
                        else if(operation === "subtract")
                        return a - b;
                        else return "No / Invalid Operation Selected"
            }
        }
    }
    
    const mul = evaluate("multiply");
    console.log(mul(1)(2));   //2
    console.log(mul(5)(2));   //10
    

    Question - How to implement infinite currying

    function add(a){
        return function (b){
            if(b) return add(a+b);
            else return a;
        }
    }
    
    console.log(add(1)(2)(3)(4)(5)());
    

    Ques - Partial application is different from currying

    function sum(a) {
        return function (b, c) {
            return a * b * c
        }
    }
    
    const x = sum(10);
    
    console.log(x(1,2));
    console.log(x(3,2));
    

    Ques - Currying can be used to manipulate Dom elements

    function updateElement(id){
        return function(content){
            document.querySelector("#"+id).textContent=content;
        }
    }
    
    const selectedele = updateElement('id');
    selectedele("WE NEED TO COOK JESSE")
    

    Ques - Curry Implementation

    Objects

    Objects are a collection of key & property values
    let car = {
        brand: "honda",
        color : "red",
        type : "AWD"
    }
    
    delete car.brand   // deletes property
    console.log(car);  //{color: 'red', type: 'AWD'}
    
    let property_var = "firstname"
    let value = "john",
    car={
       "property with spaces": true,
       [property_var] : value
    }
    
    console.log(car[property with spaces])    //Accessed using
    

    Traverse Object

    let car = {
        brand: "honda",
        color : "red",
        type : "AWD"
    }
    
    for(key in car){
        console.log(car[key]);
    }
    

    Ques - Double all numeric values of object

    let car = {
        num1: 40,
        num2: 60,
        type : "AWD"
    }
    
    for(key in car){
        if(typeof(car[key]) == "number") car[key] = car[key]*2;
        console.log(car[key]);
    }
    
    //curry function for the same
    
    function currydouble(obj){
        return function (n){
            for(key in obj){
                if(typeof(car[key]) == "number") car[key] = car[key]*2;
            }
        }
    }
    
    let x = currydouble(car);
    x(2);
    console.log(car);
    

    objects can't be passed as keys to other objects, it's read as "object Object"

    Ques - What's JSON.stringify() & JSON.parse() Ans - Object to string & string to object conversion.

    let car = {
        num1: 40,
        num2: 60,
        type : "AWD"
    }
    
    const stringfromobject = JSON.stringify(car);
    
    localStorage.setItem("carobj",stringfromobject);
    
    const retrieve = localStorage.getItem("carobj")
    const objectfromstring = JSON.parse(retrieve);
    
    console.log(objectfromstring.num1);
    
    JSON (JavaScript Object Notation) is a lightweight data format used for data interchange between applications. It is a text-based format that is easy to read and write for both humans and machines.
    
    In JavaScript, an object can be represented in JSON format, which makes it easy to send data between a client and a server. In JSON, all keys must be quoted, and only simple data types such as strings, numbers, booleans, and null are allowed as values.
    
    ![image](https://user-images.githubusercontent.com/108695777/232544359-6145bbbd-660c-414c-9389-aa86c3e92b15.png)
    
    ![image](https://user-images.githubusercontent.com/108695777/232544502-bdc15a10-1b15-40c7-8539-706c50291ea8.png)
    
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
    
    JSON.parse(): This method parses a JSON string and returns a JavaScript object. It takes a JSON string as input and returns a JavaScript object that represents the data.
    
    JSON.stringify(): This method converts a JavaScript object into a JSON string. It takes a JavaScript object as input and returns a JSON string that represents the data.
    
    JSON.parse() and JSON.stringify() can be used together to send data between a client and a server. For example, the client can use JSON.stringify() to convert a JavaScript object into a JSON string and send it to the server. The server can then use JSON.parse() to convert the JSON string back into a JavaScript object.
    
    JSON.parse() also has a second parameter, a reviver function, which can be used to transform the parsed data. The reviver function is called for each key-value pair in the parsed JSON, and can be used to transform values or delete keys from the result.
    

    Ques - Spread an object inside other

    let car = {
        num1: 40,
        num2: 60,
        type : "AWD"
    }
    
    const newobj = {
        hp:1000,
        ...car
    }
    
    console.log(newobj);
    

    Ques - What is destructuring in objects? Destructuring is a feature in JavaScript that allows you to extract values from arrays and objects into distinct variables.

    let car = {
        num1: 40,
        num2: 60,
        type : "AWD"
    }
    
    const { num1, type} = car       //Destructuring Object (use square brackets for Array destructuring)
    console.log(num1, type);
    
    const { num1 : customname, type:drivetype} = car  // Giving Custom name to destructured variables
    console.log(customname, drivetype);
    

    Ques - How to copy an Object to another

    let car = {
        num1: 40,
        num2: 60,
        type : "AWD"
    }
    
    const newcar = car;
    newcar.type = "4WD";
    
    // doing a=b only copies reference, so they're not independent copies
    

    Ques - What's a shallow copy & a deep copy A shallow copy may contain some references from the original object, but a deep copy is a complete clone & has no reference to the original object We can make a deep copy by stringifying & then parsing the object.

    This Keyword

    this.name = "global object"
    
    let car = {
        name: "inside object",
        insidefun : function() {
            console.log(this.name);      // inside object => this always points to parent object
        },
        childobj : {
            name : "nested child name",
    
            childfunc : function() {
                console.log(this.name);  // nested child name => this always points to parent object
            },
    
            arrowfunin : ()=>{
                console.log(this.name);  // global object => this always points to global object
            }
        },
    
        arrowfun : () =>{
            console.log(this.name);      //global object => this always points to global object
        }
    }
    
    car.childobj.arrowfunin()
    

    When arrow function points to normal parent function instead of global object

    this.name = "global object"
    
    let car = {
        name: "inside object",
        
        childobj : {
            name : "nested child name",
            childfunc : function() {          //arrow function points here
                const arrowfunin = ()=>{
                    console.log(this.name);  // global object => this always points to global object or parent normal function
                }
                arrowfunin()
            },
        }
    
    }
    
    car.childobj.childfunc()            //nested child name
    

    Ques - make a calc

    const calc = {
        total: 0 ,
        add(a){
            this.total += Number(a);
            return this
        },
        subtract(b){
            this.total -= Number(b);
            return this
        },
        mulitply(c){
            this.total *= Number(c);
            return this
        },
        result(){
            return this.total
        }
    }
    
    const x = calc.add(10).add(20).mulitply(2).result();
    console.log(x);
    

    Promises

    Why do we use promises

    When executing asynchronous code, if we want to execute it in order after some another asynchronous code has executed, we write nested callback functions, This leads to complicated code called Callback Hell

    function callback1(message){
        setTimeout(() => {
            console.log("first callback " + message);
    
            function callback2(){
                setTimeout(()=>{
                    console.log("second callback " + message);
    
                    function callback3(){
                        setTimeout(()=>{
                            console.log("second callback " + message);
    
                            function callback4(){
                                setTimeout(()=>{
                                    console.log("second callback " + message);
                                },0)
                            }
                            callback4()
                        },0)
                    }
                    callback3()
    
                },0)
            }
            callback2()
        },0)
    }
    
    callback1("hello")
    

    To avoid this problem we use promises

    A Promise is in one of these states:
    pending: initial state, neither fulfilled nor rejected.
    fulfilled: meaning that the operation was completed successfully.
    rejected: meaning that the operation failed.

    Response: json() method

    The json() method of the Response interface takes a Response stream and reads it to completion. It returns a promise which resolves with the result of parsing the body text as JSON.

    Note that despite the method being named json(), the result is not JSON but is instead the result of taking JSON as input and parsing it to produce a JavaScript object.

    How to make & use new promises

    const np = new Promise((resolve, reject) =>{
        // logic to sent WHAT back via resolve & reject
        if(false){
        resolve("ResloveDataSent - this is the data sent back to promise when then is succesfully executed")
        }
        else{
        reject("errorDataSent - this is sent back to promise when it is not resolved")
        }
    })
    
    np.then((resloveDataRecieved) =>{
        console.log(resloveDataRecieved);
    }).catch((errorDataRecieved)=>{
        console.log(errorDataRecieved);
    })
    
    

    Eg-2

    const myPromise = new Promise((resolve, reject) => {
      // make a network request
      fetch('https://example.com/data')
        .then(response => response.json())
        .then(data => {
          // resolve the Promise with the retrieved data
          resolve(data);
        })
        .catch(error => {
          // reject the Promise if there was an error
          reject(error);
        });
    });
    
    myPromise
      .then(data => {
        // handle the resolved data
        console.log(data);
      })
      .catch(error => {
        // handle any errors that occurred during the Promise's execution
        console.log(error);
      });
    

    Promises are asynchronous by themselves & they resolve after all of the synchronous code has been executed

    const np = new Promise((resolve, reject) =>{
        // logic to sent WHAT back via resolve & reject
        if(true){
        resolve("ResloveDataSent - this is the data sent back to promise when then is succesfully executed")
        }
        else{
        reject("errorDataSent - this is sent back to promise when it is not resolved")
        }
    })
    
    console.log("start");
    console.log(np);
    
    np.then(data=>{
        console.log("start");    //this will be executed at last as it is asynchronous code
    })
    
    console.log("end");
    
    output :-
    
    start
    index.js:12 promise is returned as is => Promise {<fulfilled>: 'ResloveDataSent - this is the data sent back to promise when then is succesfully executed'}
    index.js:16 end
    index.js:14 ResloveDataSent - this is the data sent back to promise when then is succesfully executed
    
    

    How to chain promises

    function fun1(){
        return new Promise((resolve,reject)=>{
            resolve("hello i am first promise");
        })
    }
    
    function fun2(){
        return new Promise((resolve,reject)=>{
            resolve("hello i am second promise");
        })
    }
    
    function fun3(){
        return new Promise((resolve,reject)=>{
            resolve("hello i am third promise");
        })
    }
    
    fun1().then(data=>{
        console.log(data)
        return fun2()
    }).then(data=>{
        console.log(data)
        return fun3()
    }).then(data=>{
        console.log(data)
    })
    

    Using Promise.all to run multiple promises at once & return them in the order provided, if any single promise is not resolved then it will not return anything

    const promise1 = new Promise(resolve => setTimeout(() => resolve("Promise 1"), 1000));
    const promise2 = new Promise(resolve => setTimeout(() => resolve("Promise 2"), 500));
    const promise3 = new Promise(resolve => setTimeout(() => resolve("Promise 3"), 2000));
    
    Promise.all([promise1, promise2, promise3]).then(values => {
      console.log(values);
    });
    

    Promise.race

    Promise.race() takes an array of promises as an argument & it returns the promise that is first settled out of all the promises in the array, doesn't matter if it is resolved or rejected

    const promise1 = new Promise(resolve => setTimeout(() => resolve("Promise 1"), 1000));
    const promise2 = new Promise(resolve => setTimeout(() => resolve("Promise 2"), 500));
    const promise3 = new Promise(resolve => setTimeout(() => resolve("Promise 3"), 2000));
    
    Promise.race([promise1, promise2, promise3]).then(value => {
      console.log(value);
    });
    
    output => promise2
    

    Promise.allSettled() works the same as .all but instead it returns us the array of all promises weather they are resolved or rejected
    Promise.any() works the same as .race() but instead it gives us the first fulfilled promise instead of the first settled one(that may be resolved or rejected), .any() will give an error when all of the promises in the array are rejected

    Async Await

    Await is a keyword in JavaScript that can be used with functions that return a promise. It is used to pause the execution of an asynchronous function until the promise is resolved or rejected. This means that await allows you to write asynchronous code that looks and behaves like synchronous code, making it easier to read and understand.

    When used with async/await syntax, the code is written in a way that looks like synchronous code, but it is actually asynchronous. The await keyword is used to pause the execution of the async function until the promise returned by the asynchronous operation is resolved or rejected.

    const promise1 = new Promise(resolve => setTimeout(() => resolve("Promise 1"), 3000));
    const promise2 = new Promise((resolve,reject) => {
        reject("not resolved p2")
    });
    const promise3 = new Promise(resolve => setTimeout(() => resolve("Promise 3"), 1000));
    
    
    //await will get the settled value of the promise after it runs asynchronously & provide it to the message variable
    async function runner(){
        //without try if any of the promise gets rejected we get error in console
        try{
        const message1 = await promise1;   
        console.log(message1);
        const message2 = await promise2;  //we will move to this line after the promise/await above is settled (Orderwise)
        console.log(message2);
        const message3 = await promise3;  //if any promise fails we go to catch
        console.log(message3);
        }
        catch(error){
            console.error("error is" + error);
        }
    }
    

    Note - 1.) Synchronous code in the promise definition is being executed when it is being defined like console.log(1)
    2.) If there is no resolve in promise definition then promise execution will not go in .then() operation
    3.) if in promise chaining a single .then() fails, then it will go to the .catch() block skipping all the .then() in between, after .catch() if there is any .then() the operation resumes again.
    4.) throw "error message" is same as returning a promise with reject("error message"), .catch block will encounter it.

    Call, bind & apply

    Arrow functions are not affected by this, they always point to window or parent normal function

    Call & Apply

    const obj = {name : "Rahul"}
    
    function sayHello(age,profession) {
        return console.log("Hello " + this.name +" "+ age + profession);
    }
    
    sayHello(25,profession);              // default this. working                 Hello undefined 25software developer
    sayHello.call(obj,25,profession);     // we can point to obj for this.         Hello Rahul 25software developer
    
    //apply works exactly same, except it takes function arguments in an array
    sayHello.apply(obj, [25,"software developer"])                                 Hello Rahul 25software developer
    
    

    Bind gives us back a resusable function to which we provided the context for this.

    const bindfunc = sayHello.bind(obj);
    bindfunc(25,"software engineer");
    bindfunc(26,"ceo");
    
    or
    
    sayHello.bind(obj, 25,"software developer")() //since it returns us a function we execute it twice
    

    ???? this points to global object/window object inside setTimeout, why so, even inside child functions
    Functions can't be rebound using bound chaining

    use of bind

    function checkpassword(success, failure){
        const password = prompt("enter password");
        if(password=="password") success();
        else failure();
    }
    
    let user = {
        name : "rahul",
        loginsuccess(){
            console.log(this.name + "login successful")
        },
        loginfailed(){
            console.log(this.name + "login failed")
        }
    }
    
    checkpassword(user.loginsuccess.bind(user),user.loginfailed.bind(user));
    // we use bind because we have to pass a function, not execute it there, bind returns us a function while call & apply execute it
    

    debouncing & throttling

    debouncing = event listener functions along with a time to limit function execution that is triggered by it eg- api call while typing for searching
    throttling = event listener itself is only run after a certain amount of time, so that we don't overload js with event calls, then we can check if we want to run a function or not. eg- scrolling in a social media app, we only check if we reach the limit to fetch new content every 500ms whilst scrolling.

    Debouncing and throttling are two techniques used in JavaScript to improve the performance of event handlers that are triggered frequently.
    
    Debouncing is a technique that limits the rate at which a function is executed. When an event is triggered, a timer is started, and if the event is triggered again before the timer expires, the timer is reset. This way, the function is only called once, after a certain amount of time has passed since the last event. Debouncing is useful when you want to delay the execution of a function until a user has stopped performing a certain action, such as typing in a search box.
    
    Throttling is a similar technique that limits the rate at which a function is called, but instead of delaying the function execution, it limits the number of times the function can be called within a certain time period. Throttling is useful when you want to limit the frequency of a function call to a certain maximum, such as when handling a scroll event.
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    const debouncedcount = ._debounce(()=>{
        count.innerHTML = ++triggercount;
    },800)
    
    const throttledcount = ._throttle(()=>{
        count.innerHTML = ++triggercount;
    },800)
    
    now we can use debouncedcount() & throttledcount() inside eventlistener functions
    

    Miscallaneous

    fetching & displaying data

    **apicall (eg-fetch) returns another promise, which we cannot use directly, so we have to use another .then()
    const apicall = fetch('https://my-json-server.typicode.com/FreSauce/json-ipl/data');    // apicall is fetch
        
    apicall.then((response) =>{    //response is not promise                                //response is response object
       return response.json();     // now it becomes a promise                              
       //response.json() is our data, returning it is very important since then we will get data from these async operations in .then() chaining
    }).then((data)=>{
        document.querySelector('#text').innerText = JSON.stringify(data);   //this converts promise to data
        console.log(data);
    })
    
    //this will not work as data is still a promise
    // apicall.then((response) =>{
    //    const data = response.json();
    //    document.querySelector('#text').innerText = JSON.stringify(data); 
    //    console.log(JSON.stringify(data));
    // })
    

    Same thing with async await

    async function apicall(){
        const response = await fetch('https://my-json-server.typicode.com/FreSauce/json-ipl/data');
        const data = await response.json();
        console.log(data);
    }
    apicall()
    

    return response.json() then we get data from this response object in next .then()
    response object contains status code etc, while promise contains state & result
    We have to use JSON.stringify(data) to display data inside an html element, else it will show as object Object.

    How to sort data in an array of objects, based on object property

    data.sort((a, b) => {
            return a.NRR - b.NRR;
        });
    

    How to display data in a table using fetch

    async function apicall(){
        const response = await fetch('https://my-json-server.typicode.com/FreSauce/json-ipl/data');
        const data = await response.json();
        data.sort((a, b) => {
            return a.NRR - b.NRR;
        });
        console.log(data);
        const tbody = document.querySelector(".body-parent");
    
        data.forEach((item)=>{        //item is an array element from data array
            const newtr = document.createElement("tr");
            for(const prop in item){  //item is object, prop is object key
                const tdprop = document.createElement("td");
                tdprop.innerHTML = item[prop];
                newtr.appendChild(tdprop);
            }
    
            tbody.appendChild(newtr);
        })
        
    }
    
    apicall();
    

    About

    Javascript_Theory 140322

    Resources

    Stars

    Watchers

    Forks

    Releases

    No releases published

    Packages

    No packages published