Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

In this repository, I will be talking about JavaScript and its features.

NotificationsYou must be signed in to change notification settings

ahelmi365/GET-JS-Talk

Repository files navigation

In this repository, I will be talking about JavaScript and its features. I will be covering the following topics:

Table of contents


⇧ Back to Table of Contents

Data types in JavaScript

Examples of primitive and non-primitive data types in #"auto">

  • Primitive data types

  • Non-primitive data types

    Primitive Data types VS Non-Primitive Data Types

    Primitive Data TypesNon-Primitive Data Types
    StringObject
    NumberArray
    BooleanFunction
    NullDate
    UndefinedSet
    SymbolMap

    Primitive Data Types

    1. Boolean: A boolean represents a logical value of eithertrue orfalse.
    letisRaining=true;// boolean valueconsole.log(typeofisRaining);// "boolean"
    1. Number: A number represents a numeric value, including integers and floating-point numbers.
    letage=30;// integerletprice=9.99;// floating-point numberconsole.log(typeofage);// "number"console.log(typeofprice);// "number"
    1. String: A string represents a sequence of characters.
    letmessage="Hello, world!";// stringconsole.log(typeofmessage);// "string"
    1. Undefined: A variable that has been declared but has not been assigned a value isundefined.
    letfirstName;// undefinedconsole.log(typeoffirstName);// "undefined"
    1. Null: A variable that is explicitly assigned the valuenull represents an intentional absence of any object value.
    letmiddleName=null;// nullconsole.log(typeofmiddleName);// "object"
    1. Symbol: A symbol represents a unique identifier.
    constid=Symbol("id");// symbolconsole.log(typeofid);// "symbol"

    Non-Primitive Data Types

    1. Object: An object is a collection of key-value pairs and represents a complex entity or data structure.
    constperson={firstName:"John",lastName:"Doe",age:30,hobbies:["reading","coding","traveling"],};// objectconsole.log(typeofperson);// "object"
    1. Array: An array is an ordered list of values.
    constnumbers=[1,2,3,4,5];// arrayconsole.log(typeofnumbers);// "object"
    1. Function: A function is a reusable block of code that performs a specific task.
    functiongreet(name){console.log(`Hello,${name}!`);}greet("Alice");// logs "Hello, Alice!"greet("Bob");// logs "Hello, Bob!"
    1. Date: A date represents a specific moment in time.
    constnow=newDate();// current date and timeconsole.log(typeofnow);// "object"
    1. Set: A set is a collection of unique values.
    constset=newSet([1,2,3,4,5]);// setconsole.log(typeofset);// "object"
    1. Map: A map is a collection of key-value pairs.
    constmap1=newMap();map1.set("a",1);map1.set("b",2);map1.set("c",3);console.log(map1.get("a"));// Expected output: 1map1.set("a",97);console.log(map1.get("a"));// Expected output: 97console.log(map1.size);// Expected output: 3map1.delete("b");console.log(map1.size);// Expected output: 2
    constmap=newMap([["a",1],["b",2],["c",3],]);// mapconsole.log(map);// Map(3) {"a" => 1, "b" => 2, "c" => 3}console.log(typeofmap);// "object"

    Characteristics of Primitive Data Types VS Non-Primitive Data Types

    Primitive Data TypesNon-Primitive Data Types
    ImmutableMutable
    Passed by valuePassed by reference
    Stored in stackStored in heap
    Copied by valueCopied by reference
    Compared by valueCompared by reference
    Accessed by valueAccessed by reference

    Examples on characteristics of Primitive Data Types VS Non-Primitive Data Types

    • Here are some code examples to illustrate the differences between primitive data types and non-primitive data types in #"auto">
    • Immutable vs Mutable
    • Primitive data types are immutable, meaning their value cannot be changed after they are created:

      leta="Hello";a[0]="J";// This has no effect, a remains "Hello"console.log(a);// Output: "Hello"

      Non-primitive data types are mutable, meaning their values can be changed after they are created:

      letobj={name:"John"};obj.name="Jane";// Changes the value of the 'name' propertyconsole.log(obj);// Output: {name: "Jane"}
      1. Passed by value vs Passed by reference

      Primitive data types are passed by value, meaning a copy of their value is passed to a function:

      functionchangeValue(a){a=10;}letx=5;changeValue(x);console.log(x);// Output: 5

      Non-primitive data types are passed by reference, meaning a reference to their memory location is passed to a function:

      functionchangeValue(obj){obj.name="Jane";}letperson={name:"John"};changeValue(person);console.log(person);// Output: {name: "Jane"}
      1. Stored in stack vs Stored in heap

      Primitive data types are stored in the stack:

      leta=5;

      Non-primitive data types are stored in the heap:

      letobj={name:"John"};
      1. Copied by value vs Copied by reference

      Primitive data types are copied by value:

      leta=5;letb=a;// Copies the value of a to bb=10;console.log(a);// Output: 5

      Non-primitive data types are copied by reference:

      letobj1={name:"John"};letobj2=obj1;// Copies the reference to obj1 to obj2obj2.name="Jane";console.log(obj1);// Output: {name: "Jane"}
      1. Compared by value vs Compared by reference

      Primitive data types are compared by value:

      leta=5;letb=5;console.log(a===b);// Output: true

      Non-primitive data types are compared by reference:

      letobj1={name:"John"};letobj2={name:"John"};console.log(obj1===obj2);// Output: false
      1. Accessed by value vs Accessed by reference

      Primitive data types are accessed by value:

      leta=5;letb=a;// Copies the value of a to bb=10;console.log(a);// Output: 5

      Non-primitive data types are accessed by reference:

      letobj={name:"John"};console.log(obj.name);// Output: "John"

      ⇧ Back to Table of Contents

    Strings in JavaScript

    • Strings are a sequence of characters, which can be either alphabets, numbers, special characters, or a combination of all three. They are used to represent text in a program.

    • Strings are immutable, meaning their values cannot be changed after they are created.

    • Strings are primitive data types in JavaScript, which means they are copied by value.

    • Strings are stored in the stack.

    • Strings are compared by value.

    • Strings are accessed by value.

      Declaring Strings in JavaScript

      • Strings can be declared using single quotes, double quotes, or backticks. Here are some examples:
      letstr1="Hello";letstr2="World";letstr3=`Hello World`;
      • The backtick is a new addition to JavaScript, and it allows you to use template literals. Template literals are enclosed by backticks, and they allow you to embed expressions inside a string. Here is an example:
      letname="John";letstr=`Hello${name}`;console.log(str);// Output: "Hello John"
      • Template literals are useful when you want to create a string that contains variables or expressions.
      • You can also use backticks to create multi-line strings:
      letstr=`This is amulti-line string`;
      • This is useful when you want to create a string that spans multiple lines.
      • You can also use backticks to create strings that contain single quotes or double quotes:
      letstr1=`This string contains a single quote (')`;letstr2=`This string contains a double quote (")`;
      • This is useful when you want to create a string that contains single quotes or double quotes.
      • You can also use backticks to create strings that contain backticks:
      letstr=`This string contains a backtick (\`)`;
      • This is useful when you want to create a string that contains backticks.

      String Methods in JavaScript

      • Strings have many built-in methods that allow you to perform operations on them. Here are some common string methods in alphabetical order:

        charAt()

        • ThecharAt() method returns the character at the specified index in a string. The index of the first character is 0, the index of the second character is 1, and so on. If the index is greater than or equal to the length of the string,charAt() returns an empty string.

          letstr="Hello World";console.log(str.charAt(0));// Output: "H"console.log(str.charAt(1));// Output: "e"console.log(str.charAt(2));// Output: "l"console.log(str.charAt(3));// Output: "l"console.log(str.charAt(4));// Output: "o"console.log(str.charAt(10));// Output: "d"console.log(str.charAt(11));// Output: ""

        charCodeAt()

        • ThecharCodeAt() method returns the Unicode value of the character at the specified index in a string. The index of the first character is 0, the index of the second character is 1, and so on. If the index is greater than or equal to the length of the string,charCodeAt() returns NaN.

          letstr="Hello World";console.log(str.charCodeAt(0));// Output: 72console.log(str.charCodeAt(1));// Output: 101console.log(str.charCodeAt(2));// Output: 108console.log(str.charCodeAt(3));// Output: 108console.log(str.charCodeAt(4));// Output: 111console.log(str.charCodeAt(10));// Output: 100console.log(str.charCodeAt(11));// Output: NaN

        concat()

        • Theconcat() method combines two or more strings and returns a new string. This method does not change the existing strings, but instead returns a new string.

          letstr1="Hello";letstr2="World";console.log(str1.concat(" ",str2));// Output: "Hello World"

        endsWith()

        • TheendsWith() method determines whether a string ends with the characters of a specified string. This method returns true if the string ends with the specified string, and false otherwise.

          letstr="Hello World";console.log(str.endsWith("World"));// Output: trueconsole.log(str.endsWith("World!"));// Output: false

        includes()

        • Theincludes() method determines whether a string contains the characters of a specified string. This method returns true if the string contains the specified string, and false otherwise.

          letstr="Hello World";console.log(str.includes("World"));// Output: trueconsole.log(str.includes("World!"));// Output: false

        indexOf()

        • TheindexOf() method returns the index of the first occurrence of a specified value in a string. This method returns -1 if the value is not found.

          letstr="Hello World";console.log(str.indexOf("World"));// Output: 6console.log(str.indexOf("World!"));// Output: -1

        lastIndexOf()

        • ThelastIndexOf() method returns the index of the last occurrence of a specified value in a string. This method returns -1 if the value is not found.

          letstr="Hello World";console.log(str.lastIndexOf("World"));// Output: 6console.log(str.lastIndexOf("World!"));// Output: -1

        match()

        • Thematch() method searches a string for a match against a regular expression, and returns the matches, as an Array object.

          constparagraph="The quick brown fox jumps over the lazy dog. It barked.";constregex=/[A-Z]/g;constfound=paragraph.match(regex);console.log(found);// Expected output: Array ["T", "I"]

        macthAll()

        • ThematchAll() method returns an iterator of all results matching a string against a regular expression, including capturing groups.

          constregexp=/t(e)(st(\d?))/g;conststr="test1test2";constfound=str.matchAll(regexp);constarray=[...found];console.log(array[0]);// Expected output: Array ["test1", "e", "st1", "1"]console.log(array[1]);// Expected output: Array ["test2", "e", "st2", "2"]

        padStart()

        • The padStart() method pads the current string with another string until the resulting string reaches the given length. The padding is applied from the start of the current string.

          letstr="Hello World";console.log(str.padStart(15," "));// Output: "     Hello World"console.log(str.padStart(15,"Hello "));// Output: "Hello Hello World"console.log(str.padStart(15,"*"));// Output: "---**Hello World"

        padEnd()

        • The padEnd() method pads the current string with another string until the resulting string reaches the given length. The padding is applied from the end of the current string.

          letstr="Hello World";console.log(str.padEnd(15," "));// Output: "Hello World     "console.log(str.padEnd(15," World"));// Output: "Hello World World"console.log(str.padEnd(15,"*"));// Output: "Hello World---**"

        repeat()

        • Therepeat() method returns a new string with a specified number of copies of the string it was called on.

          letstr="Hello World";console.log(str.repeat(3));// Output: "Hello WorldHello WorldHello World"

        replace()

        • The replace() method searches a string for a specified value, or a regular expression, and returns a new string where the specified values are replaced.

          letstr="Hello World";console.log(str.replace("World","World!"));// Output: "Hello World!"

        replaceAll()

        • ThereplaceAll() method returns a new string with all matches of a pattern replaced by a replacement.

          letstr="Hello World";console.log(str.replaceAll("World","World!"));// Output: "Hello World!"

        search()

        • Thesearch() method searches a string for a specified value, or regular expression, and returns the position of the match. The search value can be string or a regular expression pattern. This method returns -1 if no match is found.

          letstr="Hello World";console.log(str.search("World"));// Output: 6console.log(str.search("World!"));// Output: -1

        slice()

        • Theslice() method extracts a section of a string and returns it as a new string, without modifying the original string. This method takes two parameters: the start index and the end index (end index is not included).

          letstr="Hello World";console.log(str.slice(0,5));// Output: "Hello"console.log(str.slice(6,11));// Output: "World"
        • UsingpadStart() withslice() to mask a string:

          constfullNumber="2034399002125581";constlast4Digits=fullNumber.slice(-4);// => "5581"constmaskedNumber=last4Digits.padStart(fullNumber.length,"*");console.log(maskedNumber);// Expected output: "---5581"
        • UsingpadEnd() withslice() to mask a string:

          constfullNumber="2034399002125581";constlast4Digits=fullNumber.slice(-4);// => "5581"constmaskedNumber=last4Digits.padEnd(fullNumber.length,"*");console.log(maskedNumber);// Expected output: "5581---

        split()

        • Thesplit() method splits a string into an array of substrings, and returns the new array. This method takes two parameters: the separator and the limit.

          letstr="Hello World";console.log(str.split(" "));// Output: ["Hello", "World"]console.log(str.split(" ",1));// Output: ["Hello"]

        startsWith()

        • ThestartsWith() method determines whether a string begins with the characters of a specified string. This method returns true if the string begins with the specified string, and false otherwise.

          letstr="Hello World";console.log(str.startsWith("Hello"));// Output: trueconsole.log(str.startsWith("Hello!"));// Output: false

        substr()

        • Thesubstr() method returns a portion of the string, starting at the specified index and extending for a given number of characters afterwards. This method takes two parameters: the start index and the length.

          letstr="Hello World";console.log(str.substr(0,5));// Output: "Hello"console.log(str.substr(6,5));// Output: "World"

        substring()

        • Thesubstring() method returns a portion of the string, starting at the specified index and extending for a given number of characters afterwards. This method takes two parameters: thestart index and theend index (end index is not included).

          letstr="Hello World";console.log(str.substring(0,5));// Output: "Hello"console.log(str.substring(6,11));// Output: "World"

        toLowerCase()

        • ThetoLowerCase() method converts a string to lowercase letters.

          letstr="Hello World";console.log(str.toLowerCase());// Output: "hello world"

        toUpperCase()

        • ThetoUpperCase() method converts a string to uppercase letters.

          letstr="Hello World";console.log(str.toUpperCase());// Output: "HELLO WORLD"

        trim()

        • Thetrim() method removes whitespace from both ends of a string.

          letstr="   Hello World   ";console.log(str.trim());// Output: "Hello World"

        trimStart()

        • ThetrimStart() method removes whitespace from the beginning of a string.

          letstr="   Hello World   ";console.log(str.trimStart());// Output: "Hello World   "

        trimEnd()

        • ThetrimEnd() method removes whitespace from the end of a string.

          letstr="   Hello World   ";console.log(str.trimEnd());// Output: "   Hello World"

      ⇧ Back to Table of Contents

    Declaring Objects in JS

    In JavaScript, there are multiple ways to declare an object. Here are some common methods:

    1. Object Literal

    The most common way to create an object in JavaScript is to use an object literal. This is simply a comma-separated list of name-value pairs inside curly braces.

    constperson={name:"John",age:30,address:{street:"123 Main St",city:"Anytown",state:"CA",zip:"12345",},};

    2. Object Constructor

    Another way to create an object is to use the Object constructor. This method creates an empty object, which you can then add properties and methods to using dot notation.

    constperson=newObject();person.name="John";person.age=30;person.address={street:"123 Main St",city:"Anytown",state:"CA",zip:"12345",};

    3. Object.create()

    The Object.create() method creates a new object, using an existing object as the prototype. This method allows you to create an object with a specific prototype, which can be useful for inheritance.

    constpersonProto={greeting:function(){console.log("Hello, my name is "+this.name);},};constperson=Object.create(personProto);person.name="John";person.age=30;

    4.0 Prototype Chain

    • Prototype chain is a feature of JavaScript that allows objects to inherit properties and methods from other objects.

    • In JavaScript, every object has aprototype object, which is essentially another object from which the first object inherits properties and methods.

    • When a property or method is called on an object, JavaScript first looks for that property or method on the object itself.

    • If the property or method is not found, JavaScript then looks for it on the object's prototype.

    • If it is not found there, JavaScript looks on the prototype's prototype, and so on, creating achain of objects until the property or method is found or there is no further prototype to search.

    • Here is an example of prototype chain in #"auto" data-snippet-clipboard-copy-content="// Create an objectconst myObj = { a: 1,};// Create another object that inherits from myObjconst myOtherObj = Object.create(myObj);myOtherObj.b = 2;// Add a property to myObjmyObj.c = 3;// Call a method on myOtherObjconsole.log(myOtherObj.a); // Output: 1// Call a method on myOtherObj that is not defined on itconsole.log(myOtherObj.c); // Output: 3">

      // Create an objectconstmyObj={a:1,};// Create another object that inherits from myObjconstmyOtherObj=Object.create(myObj);myOtherObj.b=2;// Add a property to myObjmyObj.c=3;// Call a method on myOtherObjconsole.log(myOtherObj.a);// Output: 1// Call a method on myOtherObj that is not defined on itconsole.log(myOtherObj.c);// Output: 3
  • In this example, we first create an objectmyObj with a propertya equal to1. We then create another objectmyOtherObj usingObject.create(myObj), which setsmyOtherObj's prototype tomyObj. We also givemyOtherObj its own propertyb equal to2.

  • Next, we add a propertyc tomyObj object. This means thatc is now a property ofmyObj, and therefore all objects that inherit frommyObj will also have access toc.

  • Finally, we callconsole.log(myOtherObj.a), which logs the value ofmyOtherObj.a to the console. SincemyOtherObj inherits frommyObj, it has access to thea property defined onmyObj, so the output is1. We then callconsole.log(myOtherObj.c), which logs the value ofmyOtherObj.c to the console.myOtherObj does not have its ownc property, so JavaScript looks forc onmyOtherObj's prototype object (which ismyObj), and finds it there. Therefore, the output is3.

  • This example demonstrates the basics of prototype chain in JavaScript. By using prototype inheritance, we can create complex object hierarchies and easily share properties and methods between objects.

  • 4.1 Function Constructor

    In JavaScript, a function constructor is a function that is used to create objects.

    • A function constructor is defined using thefunction keyword, and it is conventionally named with an initialuppercase letter to differentiate it from regular functions.

    • The function constructor is called with thenew keyword to create new objects.

    • Here's an example:

      // Function constructorfunctionPerson(name,age){this.name=name;this.age=age;}// Creating objects using the function constructorconstperson1=newPerson("John",30);constperson2=newPerson("Jane",25);// Accessing the properties of the objectsconsole.log(person1.name);// Output: "John"console.log(person2.age);// Output: 25
    • In the example above, we define a function constructorPerson that takes two parameters,name andage. When the function constructor is called with thenew keyword, it creates a new object and sets thename andage properties on the object using thethis keyword.

    • We create two objectsperson1 andperson2 using thePerson function constructor and access their properties using dot notation.

    • Function constructors can be useful for creating multiple objects with similar properties and methods. By defining a function constructor, we can create objects with the same set of properties and methods without duplicating code. We can also add methods to the prototype object of the function constructor to allow all objects created by the constructor to inherit those methods.

    4.2 Adding Methods to the Prototype

    • In JavaScript, you can add methods to a function constructor by adding them to theprototype property of the constructor function.

    • Here's an example:

      // Function constructorfunctionPerson(name,age){this.name=name;this.age=age;}// Adding a method to the prototype object of the function constructorPerson.prototype.greet=function(){console.log("Hello, my name is "+this.name);};// Creating an object using the function constructorconstperson1=newPerson("John",30);// Calling the method added to the prototype objectperson1.greet();// Output: "Hello, my name is John"
    • In this example, we define a function constructorPerson and add agreet method to its prototype object. Thegreet method uses thethis keyword to refer to the current object and logs a greeting to the console.

    • When we create a new objectperson1 using thePerson function constructor, the[[Prototype]] of the object is set to thePerson.prototype object, so thegreet method is available on the object. We call thegreet method onperson1, and it logs a greeting to the console.

    • Adding methods to the prototype object of a function constructor allows all objects created by the constructor to inherit those methods. This can be more memory-efficient than adding methods directly to each object, as the methods are shared among all objects created by the constructor.

    4.3.1 What happen when we call afunction constructor without thenew keyword in js?

    • When a function constructor is called without thenew keyword in JavaScript, it does not create a new object to serve as thethis value for the function. Instead, the function will execute in the global context (i.e., thewindow object in the browser or theglobal object in Node.js) and any properties or methods that are defined within the function will be added to the global object.

    • For example, consider the following function constructor:

      functionPerson(name,age){this.name=name;this.age=age;}
    • If you call this constructor with thenew keyword like this:

      constperson1=newPerson("John",30);
    • A new object will be created andthis will refer to that object.person1 will be an instance of thePerson object with its ownname andage properties.

    • However, if you call the constructor without thenew keyword like this:

      constperson2=Person("Jane",25);
    • The function will execute in the global context andthis will refer to the global object. Thename andage properties will be added to the global object instead of a new object.person2 will be undefined, since the function does not return anything explicitly.

    • It's generally considered a best practice to always use thenew keyword when calling function constructors in JavaScript to avoid unintended side effects and to ensure that thethis value is set correctly.

    4.3.2 How to make sure that thenew keyword is used to call thefunction constructor?

    • To ensure that the new keyword is used when calling a function constructor in JavaScript, you can use the following technique:

    • You can use thenew.target meta property to check if the new keyword is used when calling a function constructor in JavaScript.

    • Thenew.target property is available inside a function constructor and its value will be a reference to the constructor function that was called with thenew keyword.

    • If the function is called without thenew keyword,new.target will beundefined.

    • Here's an example of how you can usenew.target to check if thenew keyword is used:

      functionPerson(name,age){// Check if the function is called with the new keywordif(!new.target){returnnewPerson(name,age);}// Otherwise, continue with the normal constructor logicthis.name=name;this.age=age;}

    4.4 Excersise on Function Constructor

    4.4.1 Excersise 1

    • Create aCar function constructor that takes three parameters:make,model, andyear.

    • The function constructor should set these properties on the object created by it.

    • Add a method to the Car function constructor's prototype object calledstart(). This method should log a message to the console indicating that the car has started.

    • Add a method to the Car function constructor's prototype object calledstop(). This method should log a message to the console indicating that the car has stopped.

    • Create two Car objects and call theirstart() andstop() methods.

    • Here's some example code to get you started:

      constcar1=newCar("Toyota","Corolla",2020);constcar2=newCar("Honda","Civic",2019);car1.start();// Output: "The Toyota Corolla has started."car2.start();// Output: "The Honda Civic has started."
      Click to show/hide solution
      // Solution:functionCar(make,model,year){this.make=make;this.model=model;this.year=year;}Car.prototype.start=function(){console.log(`The${this.make}${this.model} has started.`);};Car.prototype.stop=function(){console.log(`The${this.make}${this.model} has stopped.`);};constcar1=newCar("Toyota","Corolla",2020);constcar2=newCar("Honda","Civic",2019);car1.start();// Output: "The Toyota Corolla has started."car2.start();// Output: "The Honda Civic has started."car1.stop();// Output: "The Toyota Corolla has stopped."car2.stop();// Output: "The Honda Civic has stopped."

    4.4.2 Excersise 2

    • Create aBankAccount function constructor that takes one parameter:balance.

    • The function constructor should set the balance property on the object created by it.

    • Add three methods to the BankAccount function constructor's prototype object:deposit(),withdraw(), andgetBalance().

    • Thedeposit() method should take a parameteramount and add it to thebalance property.

    • Thewithdraw() method should take a parameteramount and subtract it from thebalance property.

    • ThegetBalance() method shouldreturn the currentbalance.

    • Create aBankAccount object and call its deposit(),withdraw(), andgetBalance() methods.

    • Here's some example code to get you started:

      constaccount=newBankAccount(1000);console.log(account.getBalance());// Output: 1000account.deposit(500);console.log(account.getBalance());// Output: 1500account.withdraw(200);console.log(account.getBalance());// Output: 1300
      Click to show/hide solution
      // Solution:functionBankAccount(balance){this.balance=balance;}BankAccount.prototype.deposit=function(amount){this.balance+=amount;};BankAccount.prototype.withdraw=function(amount){if(amount>this.balance){console.log("Insufficient funds.");return;}this.balance-=amount;};BankAccount.prototype.getBalance=function(){returnthis.balance;};constaccount=newBankAccount(1000);console.log(account.getBalance());// Output: 1000account.deposit(500);console.log(account.getBalance());// Output: 1500account.withdraw(200);console.log(account.getBalance());// Output: 1300account.withdraw(2000);// Output: "Insufficient funds."

    5. ES6 Classes

    • ES6 introduced the class syntax, which provides a more traditional object-oriented programming approach to creating objects.

      classPerson{constructor(name,age){this.name=name;this.age=age;}greeting(){console.log("Hello, my name is "+this.name);}}constperson=newPerson("John",30);
    • These are some of the common ways to declare objects in JavaScript. Depending on your use case, one method may be more appropriate than the others.

    5.1 Excersise on ES6 Classes

    • Convert theCar function constructor from the previous exercise to an ES6 class.

      Click to show/hide solution
      classCar{// Your code hereconstructor(make,model,year){this.make=make;this.model=model;this.year=year;}start(){console.log(`The${this.make}${this.model} has started.`);}stop(){console.log(`The${this.make}${this.model} has stopped.`);}}
    • Create twoCar objects and call theirstart() andstop() methods.

      Click to show/hide solution
      // Solution:constcar1=newCar("Toyota","Corolla",2020);constcar2=newCar("Honda","Civic",2019);car1.start();// Output: "The Toyota Corolla has started."car2.start();// Output: "The Honda Civic has started."car1.stop();// Output: "The Toyota Corolla has stopped."car2.stop();// Output: "The Honda Civic has stopped."

    5.2 Excersise on ES6 Classes

    • Convert theBankAccount function constructor from the previous exercise to an ES6 class.

      Click to show/hide solution
      // Solution:classBankAccount{constructor(balance){this.balance=balance;}deposit(amount){this.balance+=amount;}withdraw(amount){if(amount>this.balance){console.log("Insufficient funds.");return;}this.balance-=amount;}getBalance(){returnthis.balance;}}
    • Create aBankAccount object and call its deposit(),withdraw(), andgetBalance() methods.

      Click to show/hide solution
      // Solution:constaccount=newBankAccount(1000);console.log(account.getBalance());// Output: 1000account.deposit(500);console.log(account.getBalance());// Output: 1500account.withdraw(200);console.log(account.getBalance());// Output: 1300account.withdraw(2000);// Output: "Insufficient funds."

    ⇧ Back to Table of Contents

    Copy Objects in JS

    In JavaScript, objects are non-primitive data types and are stored in the heap. When an object is assigned to a variable or passed as an argument to a function, a reference to its memory location is copied, not a copy of its value.

    There are two ways to create a copy of an object:

    • Shallow Copy

    • Deep Copy

      1. Shallow copy

      • Shallow copy creates a new object that shares the same memory references as the original object for its properties.

      • This means that if the property value is an object, the new object will reference the same memory location as the original object.

      • Shallow copy is achieved through theObject.assign() method or thespread operator (ES6).

        • Here's an example of shallow copying an object usingObject.assign():

          letoriginalObj={name:"John",age:30,address:{street:"123 Main St",city:"Anytown",state:"CA",},};letnewObj=Object.assign({},originalObj);console.log(newObj);// Output: {name: "John", age: 30, address: {street: "123 Main St", city: "Anytown", state: "CA"}}console.log(originalObj===newObj);// Output: falseconsole.log(originalObj.address===newObj.address);// Output: true

          As you can see, thenewObj is a shallow copy oforiginalObj.newObj has its own memory space, but the "address" property ofnewObj references the same memory location as the "address" property oforiginalObj.

        • Here's an example ofshallow copying an object using thespread operator:

          letoriginalObj={name:"John",age:30,address:{street:"123 Main St",city:"Anytown",state:"CA",},};letnewObj={ ...originalObj};console.log(newObj);// Output: {name: "John", age: 30, address: {street: "123 Main St", city: "Anytown", state: "CA"}}console.log(originalObj===newObj);// Output: falseconsole.log(originalObj.address===newObj.address);// Output: true

          As you can see, thenewObj is a shallow copy oforiginalObj.newObj has its own memory space, but the "address" property ofnewObj references the same memory location as the "address" property of originalObj.

      2. Deep copy

      • Deep copy, on the other hand, creates a completely new object with its own memory space for all properties, including those that are objects themselves.

      • This ensures that changes made to the copied objectdo not affect the original object or any other copies of the object.

      • There are different ways to achievedeep copy, one of which is using theJSON.parse() andJSON.stringify() methods.

      • TheJSON.parse() andJSON.stringify() methods can be used to copy an object, creating a deep copy. This method works by first serializing the original object to a JSON string usingJSON.stringify(), and then deserializing the JSON string back into an object usingJSON.parse().

        • Here's an example of deep copying an object usingJSON.parse() andJSON.stringify():

          letoriginalObj={name:"John",age:30,address:{street:"123 Main St",city:"Anytown",state:"CA",},};letnewObj=JSON.parse(JSON.stringify(originalObj));console.log(newObj);// Output: {name: "John", age: 30, address: {street: "123 Main St", city: "Anytown", state: "CA"}}console.log(originalObj===newObj);// Output: falseconsole.log(originalObj.address===newObj.address);// Output: false

          As you can see,newObj is a deep copy oforiginalObj.newObj has its own memory space for all properties, including the "address" property. Therefore, changes made tonewObj will not affect theoriginalObj or any other copies of the object.

          ***Note that usingJSON.parse() andJSON.stringify() may not work for all cases, such as when the object containsfunctions orsymbols. In those cases, other methods of deep copying may be necessary.


      ⇧ Back to Table of Contents

      Other examples to use Spread Operator:

      • The spread operator is a new addition to the set of operators in JavaScript ES6. It takes in an iterable (e.g an array) and expands it into individual elements.

      • The spread operator is commonly used to make shallow copies of JS objects. Using this operator makes the code concise and enhances its readability.

      • Examples with Arrays:

        constarr=[1,2,3];console.log(...arr);
        constarr=[1,2,3];constarr2=[4,5,6];constarr3=[...arr, ...arr2];console.log(arr3);
        constarr=[1,2,3];constarr2=[...arr,4,5,6];console.log(arr2);
        • Example with Objects:
        constperson={name:"John",age:30};constclone={ ...person};console.log(clone);
        constperson={name:"John",age:30};constclone={ ...person,location:"USA"};console.log(clone);
        constperson={name:"John",age:30};constclone={location:"USA", ...person};console.log(clone);
        constperson={name:"John",age:30};constclone={ ...person,age:40};console.log(clone);
        constperson={firstName:"John",lastName:"Doe",age:30};constaddress={city:"New York",state:"NY",zip:"10001"};constuser={ ...person, ...address};console.log(user);

      ⇧ Back to Table of Contents

    Declaring Functions in js

    In JavaScript, there are several ways to declare functions. Here are some of the most common ones:

    1. Function Declaration: This is the most common way to declare a function. It uses the "function" keyword followed by the function name, parameters, and function body.

      functionfunctionName(parameter1,parameter2){// function bodyreturnsomething;}
    2. Function Expression: In this method, you declare a function as a variable andassign it a value using the "function" keyword.

      varfunctionName=function(parameter1,parameter2){// function bodyreturnsomething;};
    3. Arrow Function: This is a new way to declare functions in ES6 (ECMAScript 2015). Arrow functions are shorter and have a more concise syntax compared to regular functions.

      varfunctionName=(parameter1,parameter2)=>{// function bodyreturnsomething;};varfunctionName=parameter1=>{// function body to do something and then return somethingreturnsomething;};varfunctionName=(parameter1,parameter2)=>returnsomething;varfunctionName=parameter1=>returnsomething;
    4. Method Definition: This is used to declare a function as aproperty of anobject.

      varobj={functionName:function(parameter1,parameter2){// function bodyreturnsomething;},};

    ⇧ Back to Table of Contents

    Types of functions in JS

    Some examples of different types of functions in JavaScript based on their behavior and side-effects:

    1. Pure function:

      A pure function is a function that doesn't modify any data outside of its own scope and always returns the same result for the same input. Here is an example:

      functionadd(a,b){returna+b;}
    2. Impure function:

      An impure function is a function that modifies data outside of its own scope or has side effects. Here is an example:

      letcount=0;functionincrementCount(){count++;}
    3. Higher-order function:

      A higher-order function is a function that takes one or more functions as arguments or returns a function as its result. Here is an example:

      functionmultiplyBy(num){returnfunction(x){returnx*num;};}constdouble=multiplyBy(2);console.log(double(5));// Output: 10
    4. Recursive function:

      A recursive function is a function that calls itself until a certain condition is met. Here is an example:

      functionfactorial(num){if(num===0||num===1){return1;}returnnum*factorial(num-1);}console.log(factorial(5));// Output: 120
    5. Arrow function:

      An arrow function is a more concise syntax for writing a function in JavaScript. Here is an example:

      constadd=(a,b)=>{returna+b;};console.log(add(2,3));// Output: 5
    6. Generator function:

    A generator function is a function that can pause its execution and return multiple values one at a time. Here is an example:

    function*processNumbers(numbers){for(constnumofnumbers){// Perform some operation on numconstresult=num*2;// Pause the iteration and yield the resultyieldresult;}}functiondoSomething(){console.log("Doing something...");}constnumbers=[1,2,3,4,5];constgen=processNumbers(numbers);// Iterate over the generator and pause after each resultconsole.log(gen.next().value);// 2doSomething();console.log(gen.next().value);// 4doSomething();console.log(gen.next().value);// 6doSomething();console.log(gen.next().value);// 8doSomething();console.log(gen.next().value);// 10

    ⇧ Back to Table of Contents

    Functions are First Class Objects

    • In javaScript functions are considered first-class objects, which means they can be treated like any other value or object. This means that:

      • Functions can be assigned to variables:

        constadd=function(a,b){returna+b;};console.log(add(2,3));// 5
      • Functions can be returned as values from functions:

        functionmultiply(x,y){returnx*y;}// multiply 3,4,5, by 2multiply(2,3);//6multiply(2,4);// 8multiply(2,5);// 10// multiply 3,4,5, by 3multiply(3,3);// 9multiply(3,4);// 12multiply(3,5);// 15
        functionmultiplyByTwo(x){returnx*2;}functionmultiplyByThree(x){returnx*3;}functionmultiplyByFour(x){returnx*4;}
        functionmakeMultiplier(factor){returnfunction(number){returnnumber*factor;};}constmultiplyByTwo=makeMultiplier(2);// multiply 3,4,5, by 2console.log(multiplyByTwo(3));// 6console.log(multiplyByTwo(4));// 8console.log(multiplyByTwo(5));// 10constmultiplyByThree=makeMultiplier(3);// multiply 3,4,5, by 3console.log(multiplyByThree(3));// 9console.log(multiplyByThree(4));// 12console.log(multiplyByThree(5));// 15
        • When a function returns another function as its result, it is called a "closure".
        • Aclosure is a function that has access to variables in its outer (enclosing) scope, even after the outer function has returned.
      • Functions can be stored in data structures like arrays or objects:

        constoperations={add:function(a,b){returna+b;},subtract:function(a,b){returna-b;},multiply:function(a,b){returna*b;},divide:function(a,b){returna/b;},};console.log(operations.add(2,3));// 5console.log(operations.divide(10,2));// 5
      • Functions can be passed as arguments to other functions:

        functiongreeting(name){console.log(`Hello,${name}!`);}functiongreetingWrapper(fn,name){console.log("Preparing to greet...");fn(name);console.log("Greeting complete.");}greetingWrapper(greeting,"Alice");// Output:// Preparing to greet...// Hello, Alice!// Greeting complete.

    ⇧ Back to Table of Contents

    JS is single-threaded programming language

    • JS issingle-threaded programming language, which means it can only execute one task at a time.
    • This is because it has only onecall stack, which is responsible for executing the code.
    • This means that if a function is currently executing, no other code can run until the call stack is clear.
    • This can be a problem if a function takes a long time to execute, because it will block the call stack and prevent other code from running. This is known asblocking code.
    • Blocking code can be a problem in JavaScript because it can make the user interface unresponsive.
    • For example, if a function takes a long time to execute, the user will not be able to interact with the page until the function is finished executing.
    • This can be a problem if the function is doing something that is not related to the user interface, such as fetching data from a server or performing a complex calculation.
    • To solve this problem, JavaScript developers often useasynchronous programming techniques, such ascallbacks,promises, andasync/await, to allow the application to continue running while it waits for long-running tasks to complete.
    • This allows the user interface to remain responsive while the application is performing long-running tasks.

    ⇧ Back to Table of Contents

    Callback Functions

    • A callback is a function that is passed as an argument to another function
    • And is executed after some operation has been completed

    Challenges solved by callback function in js:

    1. Code duplication

    • Example to show the problem without callback function:

      // breaking the DRY principleconstnums=[1,2,3,4,5,6,7,8,9,10];console.log(nums);functioncopyArrayAndMultiplyByTwo(array){constoutput=[];for(leti=0;i<array.length;i++){output.push(array[i]*2);}returnoutput;}constnumbers1=copyArrayAndMultiplyByTwo(nums);// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]functioncopyArrayAndDivideByTwo(array){constoutput=[];for(leti=0;i<array.length;i++){output.push(array[i]/2);}returnoutput;}constnumbers2=copyArrayAndDivideByTwo(nums);// [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]functioncopyArrayAndAddTwo(array){constoutput=[];for(leti=0;i<array.length;i++){output.push(array[i]+2);}returnoutput;}constnumbers3=copyArrayAndAddTwo(nums);// [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    • The solution using callback function

      // using the callback functions:functionmultiplyByTwo(number){returnnumber*2;}functiondivideByTwo(number){returnnumber/2;}functionaddTwo(number){returnnumber+2;}functioncopyArray(array,instructions){constnewArray=[];array.forEach((element)=>{newArray.push(instructions(element));});returnnewArray;}constnumbers=[1,2,3,4,5,6,7,8,9,10];console.log(numbers);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]constnewNumbers=copyArray(numbers,multiplyByTwo);console.log(newNumbers);// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]constnewNumbers2=copyArray(numbers,divideByTwo);console.log(newNumbers2);// [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]constnewNumbers3=copyArray(numbers,addTwo);console.log(newNumbers3);// [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
      • You don't need to create a new function for each operation
      • You can pass a annonymous/arrow function as an argument to another function
      // Passing annonymous function as arguments to another functionconstnewNumbers4=copyArray(numbers,function(number){returnnumber+2;});console.log(newNumbers4);// [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]// Passing arrow function as arguments to another functionconstnewNumbers5=copyArray(numbers,(number)=>number+2);console.log(newNumbers5);// [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

    2. Callback function to handle events in the browser

    • Example to show how to use callback function to handle events in the browser

      constbutton=document.querySelector("button");functionhandleClick(event){console.log("Button clicked!");}button.addEventListener("click",handleClick);

    3. Asynchronous programming

    • In asynchronous programming, a function may take some time to complete its operation. This can cause the program to pause or become unresponsive.

    • Callbacks provide a way to avoid this by allowing the program to continue executing while the asynchronous function is running in the background.

      functiongetData(callback){setTimeout(()=>{constdata={name:"John Doe",age:30};callback(data);},1000);}functionprocessData(data){console.log(`Name:${data.name}, Age:${data.age}`);}getData(processData);// Output after 1 second: Name: John Doe, Age: 30
    • The above example shows how callbacks can be used to handle asynchronous operations in JavaScript.

    • ThegetData() function takes a callback function as an argument and executes it after one second.

    • TheprocessData() function is passed as an argument to thegetData() function and is executed after one second.

    • TheprocessData() function receives the data object as an argument and logs it to the console.

    • ThegetData() function is called with theprocessData() function as an argument.

    • ThegetData() function executes theprocessData() function after one second and passes the data object as an argument.


    ⇧ Back to Table of Contents

    Higher Order Functions

    • Higher order function is a function that takes a function as an argument

      functioncopyArray(array,instructions){constnewArray=[];array.forEach((element)=>{newArray.push(instructions(element));});returnnewArray;}functionmultiplyByTwo(number){returnnumber*2;}constnumbers=[1,2,3,4,5,6,7,8,9,10];// Using the higher-order function to pass a function as an argumentconstnewNumbers=copyArray(numbers,multiplyByTwo);console.log(newNumbers);// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
    • Or a function that returns a function as a result

      // example of a function that returns a function as a result:functioncreateAdder(num){returnfunction(x){returnx+num;};}constaddTwo=createAdder(2);console.log(addTwo(10));// 12constaddFive=createAdder(5);console.log(addFive(10));// 15

    ⇧ Back to Table of Contents

    JS built-in HOF

    Examples of built-in higher-order functions in JavaScript:

    1. Array.map(): Returns a new array with the same number of elements as the original array, where each element is transformed according to a function that is passed as an argument.

      constnumbers=[1,2,3,4,5];constdoubledNumbers=numbers.map(function(num){returnnum*2;});console.log(doubledNumbers);// Output: [2, 4, 6, 8, 10]
    2. Array.filter(): Returns a new array with only the elements that pass a test implemented by a function that is passed as an argument.

      constnumbers=[1,2,3,4,5];constevenNumbers=numbers.filter(function(num){returnnum%2===0;});console.log(evenNumbers);// Output: [2, 4]
    3. Array.reduce():

    • The goal of thereduce method is to reduce the array to a single value by applying a function to each element in that array (from left to right).

    • The function that is passed toreduce() takes two arguments: anaccumulator and thecurrent value in the array.

    • The function returns the updatedaccumulator, which is used as theaccumulator for the next iteration.

    • The function is called once for each element in the array.

      constnumbers=[1,2,3,4,5];constsumOfNumbers=numbers.reduce(function(acc,num){returnacc+num;},0);console.log(sumOfNumbers);// Output: 15
    • These built-in higher-order functions make it easy to write concise and expressive code that manipulates arrays.

    Promises in js

    • Promises are used to handle asynchronous operations in JavaScript.
    • Anasynchronous operation is one that doesn't block the execution of the program while it's running, but instead runs in the background andnotifies the program when it's finished.
    • APromise is an object that represents the eventual completion or failure of an asynchronous operation.
    • Promises returns an object to which you attach callbacks, instead of passing callbacks into a function.
    • APromise 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.
    // example of creating a promise using the Promise constructor:letpromise=newPromise(function(resolve,reject){// executor (the producing code, "singer")});
    • The function passed tonew Promise is called theexecutor.

    • When newPromise is created, theexecutor runs automatically. It contains the producing code which should eventually produce the result.

    • Its argumentsresolve andreject are callbacks provided by JavaScript itself.

    • When theexecutor obtains the result, it should call one of these callbacks:

      • resolve(value) — if the job finished successfully, with resultvalue.
      • reject(error) — if an error occurred,error is the error object.
    • So to summarize: theexecutor runs automatically and attempts to perform a job.

    • When it is finished with the attempt, it callsresolve if it was successful orreject if there was an error.

      constmyPromise=newPromise((resolve,reject)=>{// Do some async operation here...if(/* some condition */){resolve(/* some value */);// Fulfill the promise}else{reject(/* some error */);// Reject the promise}});myPromise.then(result=>{// The promise was fulfilled}).catch(error=>{// The promise was rejected});
    • Thepromise object returned by thenew Promise constructor has these internal properties:

      • state — initially"pending", then changes to either"fulfilled" whenresolve is called or"rejected" whenreject is called.

      • result — initiallyundefined, then changes tovalue whenresolve(value) called or toerror whenreject(error) is called.

      • So the executor eventually moves promise to one of these states:

        alt text

    • Here’s an example of apromise constructor and a simpleexecutor function with “producing code” that takes time (viasetTimeout):

      letpromise=newPromise(function(resolve,reject){// the function is executed automatically when the promise is constructed// after 5 second signal that the job is done with the result "done"setTimeout(()=>resolve("done"),5000);});console.log(promise);// Promise { <pending> }
    • We can see two things by running the code above:

      • Theexecutor is called automatically and immediately (bynew Promise).

      • Theexecutor receives two arguments:resolve andreject. These functions are pre-defined by the JavaScript engine, so we don’t need to create them. We should only call one of them when ready.

      After 5 seconds of “processing”, theexecutor callsresolve("done") to produce the result. This changes thestate of thepromise object:

      alt text

      • That was an example of a successful job completion, a“fulfilled promise”.
    • And now an example of theexecutor rejecting thepromise with anerror:

      letpromise=newPromise(function(resolve,reject){// after 5 seconds signal that the job is finished with an errorsetTimeout(()=>reject(newError("Whoops!")),5000);});console.log(promise);// Promise { <pending> }
      • The call toreject(...) moves the promise object to "rejected" state:

      alt text

      Promises-then-Catch-finally

      • APromise object serves as a link between theexecutor (the “producing code”) and theconsuming functions, which will receive theresult orerror.
      • Consuming functions can be registered (subscribed) using methods.then,.catch and.finally.

      1. then()

      • The most important, fundamental one is .then.

      • The syntax is:

        promise.then(function(result){/* handle a successful result */},function(error){/* handle an error */});
      • The first argument of.then is a function that runs when the promise isfulfilled, and receives theresult.

      • The second argument of.then is a function that runs when the promise isrejected, and receives theerror.

      • For instance, here’s a reaction to asuccessfully resolved promise:

        letpromise=newPromise(function(resolve,reject){setTimeout(()=>resolve("done!"),1000);});// resolve runs the first function in .thenpromise.then((result)=>alert(result),// shows "done!" after 1 second(error)=>alert(error)// doesn't run);
      • And in the case of arejection, the second one:

        letpromise=newPromise(function(resolve,reject){setTimeout(()=>reject(newError("Whoops!")),1000);});// reject runs the second function in .thenpromise.then((result)=>alert(result),// doesn't run(error)=>alert(error)// shows "Error: Whoops!" after 1 second);
      • If we’re interested only in successful completions, then we can provide only one function argument to.then:

        letpromise=newPromise((resolve)=>{setTimeout(()=>resolve("done!"),1000);});promise.then(alert);// shows "done!" after 1 second

      2. catch

      • If we’re interested only inerrors, then we can usenull as the first argument:.then(null, errorHandlingFunction), which is exactly the same:

        letpromise=newPromise((resolve,reject)=>{setTimeout(()=>reject(newError("Whoops!")),1000);});// .catch(f) is the same as promise.then(null, f)// promise.then(null, alert); // shows "Error: Whoops!" after 1 secondpromise.catch(alert);// shows "Error: Whoops!" after 1 second
      • The call.catch(f) is a complete analog of.then(null, f), it’s just a shorthand.

      3. finally

      • The call.finally(f) is similar to.then(f, f) in the sense thatf always runs when the promise issettled: be itresolve orreject.

      • The idea offinally is to set up a handler for performing cleanup/finalizing after the previous operations are complete.

      • E.g. stopping loading indicators, closing no longer needed connections, etc.

      • Afinally handler “passes through” theresult orerror to the next suitable handler.

      • For instance, here theresult is passed throughfinally tothen:

        newPromise((resolve,reject)=>{setTimeout(()=>resolve("value"),2000);}).finally(()=>alert("Promise ready"))// triggers first.then((result)=>alert(result));// <-- .then shows "value"
      • As you can see, thevalue returned by the firstpromise is passed throughfinally to the nextthen.

      • And here’s an example of anerror, for us to see how it’s passed throughfinally tocatch:

        newPromise((resolve,reject)=>{thrownewError("error");}).finally(()=>alert("Promise ready"))// <-- .finally handles the error.catch((err)=>alert(err));// <-- .catch handles the error object
      • Afinally handler has no arguments.

      • Infinally we don’t know whether thepromise is successful or not. That’s all right, as our task is usually to perform“general” finalizing procedures.

      • That’s very convenient, becausefinally is not meant to process apromise result. As said, it’s a place to dogeneric cleanup, no matter what the outcome was.

      • Afinally handler also shouldn’t return anything. If it does, the returned value is silently ignored.

      • The onlyexception to this rule is when afinally handler throws anerror. Then thiserror goes to thenext handler, instead of anyprevious outcome.


      ⇧ Back to Table of Contents

      Fetch

      • In frontend programming,promises are often used fornetwork requests.

      • TheFetch API provides an interface for fetching resources.

      • It is a more powerful and flexible replacement forXMLHttpRequest.

      • For making a request and fetching a resource, use thefetch() method.

      • It is a global method in Window object.

      • Thefetch() method takes one mandatory argument, thepath to the resource you want to fetch.

      • Thefetch() method does not directly return theJSON response body but instead it returns apromise that resolves with aResponse object.

      • TheResponse object, in turn, does not directly contain the actualJSON response body but is instead a representation of the entireHTTP response.

      • So, to extract theJSON body content from theResponse object, we use thejson() method.

      • Thejson() returns a secondpromise thatresolves with theresult of parsing theresponse body text asJSON.

      • json() is a method on theresponse object that returns apromise to parse the body text asJSON.

        1. Fetch to GET data:

        fetch("https://jsonplaceholder.typicode.com/todos/1")//  reads the remote data and parses it as JSON.then((response)=>response.json()).then((json)=>console.log(json));

        2. Fetch to GET data with async/await:

        constURL="https://dummyjson.com/products";fetch(URL)// returns a promise.then((res)=>res.json())// returns a promise.then((json)=>json)// returns a json object.then((data)=>{console.log(data.products);returndata.products;// for the next then()}).then((products)=>{console.log(products[0]);returnproducts[0];// for the next then()}).then((firstProduct)=>{console.log(firstProduct.title);});

        3. Fetch to POST data:

        letuser={name:"John",surname:"Smith",};letresponse=awaitfetch("/article/fetch/post/user",{method:"POST",headers:{"Content-Type":"application/json;charset=utf-8",},body:JSON.stringify(user),});letresult=awaitresponse.json();alert(result.message);
        • Explanation of the code:

        • We first create an object calleduser with two properties,name andsurname.

          letuser={name:"John",surname:"Smith",};
        • We then use thefetch() function to make aPOST request to a URL endpoint (/article/fetch/post/user in this case) and pass in anoptions object that specifies themethod,headers, andbody of the request.

        • In this case, we are sending theuser object as the requestbody after converting it to aJSON string usingJSON.stringify().

          letresponse=awaitfetch("/article/fetch/post/user",{method:"POST",headers:{"Content-Type":"application/json;charset=utf-8",},body:JSON.stringify(user),});
        • TheContent-Type header is used to indicate the media type orformat of the data being sent in thebody of anHTTP request.

        • It informs the server about how to interpret and process the data in therequest body.

        • In the provided code, theContent-Type header is set to"application/json;charset=utf-8". This specifies that the body of the request contains data inJSON format, and the character encoding used is UTF-8.

        • By setting theContent-Type header appropriately, you are providing a hint to theserver on how to handle therequest body.

        • When theserver receives therequest, it checks theContent-Type header to determine how to parse and interpret the incoming data.

        • In this case, theserver can expect the body to be inJSON format and use appropriate parsing mechanisms to convert theJSON string into anobject or perform any necessary processing.

        • In the context of theContent-Type header with"charset=utf-8", it indicates that the content of the request body is encoded using theUTF-8 character encoding. By specifying this encoding, you ensure that theserver correctly interprets and handles the text data encoded in UTF-8 format.

        • TheJSON.stringify() method is used in this code to convert theuser object into a JSON string representation.

        • When making an HTTP request, thebody of the request typically contains the data that needs to be sent to the server. However, theHTTP protocol itself only supports sendingtextual data.

        • JSON (JavaScript Object Notation) is a popular data interchange format that is widely supported and understood by many programming languages and platforms.

        • In order to include theuser object as the body of theHTTP request, it needs to be converted into a format that can be transmitted over the network.

        • By usingJSON.stringify(user), theuser object is serialized into aJSON string, which is a textual representation of the object's data.

        • This allows the data to be sent as the body content of the request.

          letuser={name:"John",surname:"Smith",};letjsonString=JSON.stringify(user);console.log(jsonString);// '{"name":"John","surname":"Smith"}'
        • On the server side, when the request is received, the server can thenparse theJSON string back into an object and access the individual properties of theuser object.

        • This is commonly done usingJSON parsing libraries orbuilt-in functionalityprovided by the server-side programming language or framework.

        • We then use thejson() method on theresponse object to parse the response body as JSON and return a JavaScript object. We store the parsed object in theresult variable usingawait since thejson() method returns aPromise.

          letresult=awaitresponse.json();
        • Finally, we display a message from the parsed JSON data using thealert() function. In this case, we assume that the response body has a property calledmessage.

          alert(result.message);

      ⇧ Back to Table of Contents

      Async

      • There’s a special syntax to work withpromises in a more comfortable fashion, called“async/await”. It’s surprisingly easy to understand and use.

      • The word“async” before a function means one simple thing: a function always returns apromise. Other values are wrapped in a resolved promise automatically.

      • let's check this function:

        functiongetEmployeesData(){constemployees=["John","Jane","Jack"];returnnewPromise((resolve,reject)=>{if(employees.length>0){resolve("Employees exist");}else{reject("Employees does not exist");}});}// call the functiongetEmployeesData().then((reolveValue)=>console.log(reolveValue),(rejectValue)=>console.error(rejectValue));
      • We can rewrite the previous function as:

        functiongetEmployeesData(){constemployees=["John","Jane","Jack"];if(employees.length>0){returnPromise.resolve("Employees exist");}else{returnPromise.reject("Employees does not exist");}}// call the functiongetEmployeesData().then((reolveValue)=>console.log(reolveValue),(rejectValue)=>console.error(rejectValue));
      • We can rewrite the previous function usingasync as:

        asyncfunctiongetEmployeesData(){constemployees=["John","Jane","Jack"];if(employees.length>0){return"Employees exist";}else{throw"Employees does not exist";}}// call the functiongetEmployeesData().then((reolveValue)=>console.log(reolveValue),(rejectValue)=>console.error(rejectValue));

      ⇧ Back to Table of Contents

      Await

      • await is a keyword that is used inside anasync function.

      • await waits for thepromise toresolve and returns the result.

      • We use theawait keyword to wait for the response to come back before moving on to the next line of code

      • await only works insideasync functions within regular JavaScript code, however it can be used on its own with JavaScriptmodules.

      • Example

        functiongetEmployeesData(){console.log("Start of getEmployeesData()");constURL="https://dummyjson.com/products";constresponse=fetch(URL);response.then((res)=>res.json()).then((json)=>json.products).then((products)=>products[0]).then((firstProduct)=>firstProduct.title).then((title)=>console.log(title));console.log("End of getEmployeesData()");}getEmployeesData();
      • The above function can be rewritten usingasync andawait as:

        asyncfunctiongetEmployeesData(){console.log("Start of getEmployeesData()");constURL="https://dummyjson.com/products";constresponse=awaitfetch(URL);// wait for this promise to resolve before moving on to the next line of code.constjson=awaitresponse.json();// wait until the resolved promise is pasred to jsonconstproducts=json.products;constfirstProduct=products[0];consttitle=firstProduct.title;console.log(title);console.log("End of getEmployeesData()");}getEmployeesData();
      • The keywordawait makes JavaScript wait until thatpromise settles and returns its result.

      • await literallysuspends the function execution until thepromise settles, and thenresumes it with thepromise result.

      • That doesn’t cost any CPU resources, because theJavaScript engine can do other jobs in the meantime: execute other scripts, handle events, etc.

      • It’s just a more elegant syntax of getting thepromise result thanpromise.then. And, it’s easier to read and write.

      • The above function can be rewritten usingtrycatchas:

        asyncfunctiongetEmployeesData(){console.log("Start of getEmployeesData()");constURL="https://dummyjson.com/products";try{constresponse=awaitfetch(URL);constjson=awaitresponse.json();constproducts=json.products;constfirstProduct=products[0];consttitle=firstProduct.title;console.log(title);}catch(error){console.log("error in catch",error);}console.log("End of getEmployeesData()");}
      • In modern browsers,await on top level works just fine, when we’re inside amodule. But if the code is not inside a module, thenawait will produce anerror.

      • Example:

        // we assume this code runs at top level, inside a moduleletresponse=awaitfetch("/article/promise-chaining/user.json");letuser=awaitresponse.json();console.log(user);

        Async/Await Other examples:

        asyncfunctionfetchData(URL){try{constresponse=awaitfetch(URL);// console.log(response);if(!response.ok){console.log(response.status);thrownewError(`HTTP error! status:${response.status}`);}constdata=awaitresponse.json();returndata;}catch(error){console.error("Error:",error);}}try{constresponse=awaitfetchData("https://dummyjson.com/products");constdata=response?.products;console.log(data);}catch(error){console.error("Error outer catch:",error);}
        asyncfunctionpostJSON(URL,data){try{constresponse=awaitfetch(URL,{method:"POST",// or 'PUT'headers:{"Content-Type":"application/json",},body:JSON.stringify(data),});constresult=awaitresponse.json();console.log("Success:",result);returnresult;}catch(error){console.error("Error:",error);}}constURL="https://example.com/profile";constdata={username:"example"};constresponse=awaitpostJSON(URL,data);

    ⇧ Back to Table of Contents

    Callback Hell and how to avoid it

    • callback hell is a situation where you have a lot of nested callbacks
    loadScript("/my/script.js",function(script){loadScript("/my/script2.js",function(script){loadScript("/my/script3.js",function(script){// ...continue after all scripts are loaded});});});
    • This code uses callbacks to load three scripts in sequence. Each time a script is loaded, the next script is loaded in the callback function.
    • This creates a "pyramid of doom" structure where the code becomes nested and hard to read. It also makes error handling difficult
    • To solve this, we can usePromises andasync/await. Here's an example of how to refactor the code using Promises and async/await:
    functionloadScript(src){returnnewPromise((resolve,reject)=>{constscript=document.createElement("script");script.src=src;script.onload=()=>{document.head.appendChild(script);resolve(script);};script.onerror=()=>reject(newError(`Failed to load script${src}`));});}asyncfunctionstart(){try{constscript1=awaitloadScript("/my/script.js");console.log(`${script1.src} loaded`);constscript2=awaitloadScript("/my/script2.js");console.log(`${script2.src} loaded`);constscript3=awaitloadScript("/my/script3.js");console.log(`${script3.src} loaded`);// continue after all scripts are loaded}catch(err){console.error(err);}}start();
    • This refactored code usesPromises to load the scripts, andasync/await to wait for each Promise toresolve before continuing with the next statement.
    • This approach makes the code much more readable and maintainable, and avoids the "pyramid of doom" structure of callback hell.

    ⇧ Back to Table of Contents

    Questions


    ⇧ Back to Table of Contents


    [8]ページ先頭

    ©2009-2025 Movatter.jp