As there are a lot of functions being talked about here you may also
  want to visit my Functions Page for more info. 
 
  
        Nearly everything in Javascript is/can be an object. 
        * Booleans can be objects 
        * Numbers can be objects 
        * Strings can be objects 
        * Dates are always objects 
        * Maths are always objects 
        * Regular expressions are always objects 
        * Arrays are always objects 
        * Functions are always objects 
        * Objects are objects 
 
        To make a string/number an object you need to... 
        var a = new String(); or var a = new String("ABCDE"); 
        var n = new Number(); or var n = new Number(123); 
 
        Objects are basically variables that contain variables (properties)...eg... 
 
        var person = {firstName:"John", lastName:"Smith", age:50} 
        So the properties of the 'person' object is:- 
        firstName / lastName & age 
        and are referred to by using... 
        person.firstName; eg x = person.firstName; 
        person.lastName; eg y = person.lastName; 
        person.age; eg a = person.age; 
 
 
        Take a look at Object
          Definitions on W3Schools website for more 
 
 
        Also take a look at Object
          Methods on mozilla website for more 
        Eg... Object.keys(Person)  //Returns a list of property names 
        & in the Related Topics section you can see more methods listed, eg 
        Object.entries(Person)  //Returns propertynames & values 
        Object.assign(target, source, source...)  //Combines objects properties on to target object
        etc 
 
 
      
        Creating a single object 
        var person = { 
              firstName:"John", 
              lastName:"Smith", 
              age:50 
          }; 
 
        or... (above is easier and more common) 
        var person = new object(); 
          person.firstName ="John"; 
          person.lastName = "Smith"; 
          person.age:50;  
 
        ****** 
 
        If you need to create more than one object of the same type then use an object constructor function 
        function person(first, last, age) { 
              this.firstName = first; 
              this.lastName = last; 
              this.age = age; 
          }; 
          var myFather = new person("Les", "Kirby", 75); 
          var myMother = new person("Lilian", "Kirby", 79);  
 
        (this. refers to the current object. So saying this.age means you are creating a property
          inside this object)  
 
        You can even create a property that is a 'function', for example...you may need the person's full name so
        you can add in a line (just below this.age = age;)... 
        this.fullName = function() { 
             return this.firstName + " " + this.lastName; 
          }; 
 
        and then the property 
        myFather.fullName() or myMother.fullName() 
        will also exist. You can also refer to it as... 
        myFather["fullName"]() or myMother["FullName"]() 
        if you want to...Note the () as 'fullName' is a function.
 
 
        Note...This is how things like Math.round()
            work... Math is an object and .round() is a method (function)...just like
            myFather is an object and .fullName() is a method (function).  
 
      
        To ADD a new PROPERTY to your object... 
        myFather.myExtraProperty = "ABCDE"; 
        (Note...You cannot add it to the function 'person' only to myFather and/or myMother.
          You will need to change the function for 'person' if you want a new property for
          ALL of your objects) 
 
        To DELETE a PROPERTY from your object... 
        delete myFather.myExtraProperty; 
        (Note...You can only delete properties that you added (above) to myFather and/or myMother.
          You will need to change the function for 'person' if you want to delete a property that came
          from the function 'person' - and it will affect ALL your objects that use 'person') 
 
      
        You can access the object's properties by using the 
          . (dot) or [] (square brackets) methods 
        Eg... 
 
        var person = { 
              firstName:"John", 
              'last Name':"Smith", 
              'my Age':50 
          }; 
 
        (Persoanally I would say DO NOT use spaces in the property names (eg 'last Name')
          as it makes it harder to code) 
 
        person.firstName  
        person['firstName']  
        person['last Name']  
        (Note...you MUST use the brackets if you created the property name within quotes (eg 'last Name') but
          I would not recommend creating properties that way as it is not the accepted way of doing it anyway) 
        
 
      
        A constructor is a function that is used when creating many objects. 
        It is good practice to name constructors with an upper-case first letter. 
 
        Show a list of Property Names and Property Values that are in my object...and use
        a constructor to base the objects myFather & myMother on....> 
      
        Constructor...  
        function Person(first, last, age) { 
              this.firstName = first; 
              this.lastName = last; 
              this.age = age; 
              this.fullName = function() { 
                 return this.firstName + " " + this.lastName}; 
          }; 
          Objects...  
          var myFather = new Person("Les", "Kirby", 75); 
          var myMother = new Person("Lilian", "Kirby", 79);  
 
        Then using a FOR loop to display the results (of myFather)... 
        (Note... In this example I have to check if one of the properties is a
          function - because person.fullName IS a function)
 
        var txt = ""; 
          for (x in myFather) { 
              if (typeof(myFather[x]) == "function") { 
                  txt += x + ": "+myFather[x]() + " <br />" 
              } else { 
                  txt += x + ": "+myFather[x] + " <br />" 
              } 
          }; 
          toDisplay("example1", txt); 
         
 
        Note... 
        If you want to add new properties to your constructor function you need to include the
        new properties as part of the original 'function'... 
BUT... 
        If you cannot do that for some reason (maybe you are reusing the code) then you must use the
        Prototype Inheritance option. 
        Eg... 
        Person.prototype.newProperty = "myValue" 
 
      
        A scenario... 
 
        //Create a constant object called 'spaceship' 
        const spaceship = { 
             homePlanet : 'Earth', 
             color : 'silver' 
          }; 
 
        //Create a function called 'paintIt' that takes 
        // one parameter called 'obj' 
        (Note.. I could have said... 
          let paintIt = function(obj) {...} but chose this strange looking (shorthand) way instead) 
        let paintIt = obj => { 
             obj.color = 'glorious gold' 
          };  
 
        //Call the 'paintIt' function and pass it the 'spaceship' object 
        //which then changes the 'color' property.
        paintIt(spaceship); 
          spaceship.color // Returns 'glorious gold'  
 
        The above shows that it remembers the change to the 'color' property even outside
          of the function 'paintIt' because it is an OBJECT and that gets treated as a BYREFERENCE object
          and not BYVALUE... 
 
          ...BUT if you ADD any new properties via the 'paintIt' function then they will get forgotten about
          when you exit the function) 
 
      
        Show a list of Property Names and Property Values that are in my object....> 
      
        
          let spaceship = { 
 
             crew: { 
 
                captain: { 
                   name: 'Lily', 
                   degree: 'Computer Engineering', 
                   cheerTeam() { console.log('You got this!') } 
                }, 
 
                'chief officer': { 
                   name: 'Dan', 
                   degree: 'Aerospace Engineering', 
                   agree() { console.log('I agree, captain!') } 
                }, 
 
                medic: { 
                   name: 'Clementine', 
                   degree: 'Physics', 
                   announce() { console.log(`Jets on!`) } 
                }, 
 
                translator: { 
                   name: 'Shauna', 
                   degree: 'Conservation Science', 
                   powerFuel() { console.log('The tank is full!') } 
                } 
 
             } 
          }; 
 
          for (let x in spaceship.crew) { 
             console.log(x + ": " + spaceship.crew[x].name + ", " + spaceship.crew[x].degree); 
          } 
        
        
        
      
        The command this. will need to be used sometimes and (hopefully)
        this will help explain it a little more 
 
        For example... 
 
        const robot = { 
             model: "1E78V2", 
             energyLevel: 100, 
             provideInfo() { 
                return `I am ${this.model} and
          my current energy level is ${this.energyLevel}.` 
             } 
          }; 
 
          console.log(robot.provideInfo()); 
 
        
        The above will print to the console the following... 
        I am 1E78V2 and my current energy level is 100. 
 
        BUT if I did not include this. in the 'provideInfo' property then
        it would have errored out saying that model and energyLevel were both
        'undefined'. 
 
        This was because it does not know where to find the property 'model' or 'energyLevel', even
        though they were defined above they were not defined inside the function provideInfo. 
 
        So...adding this. before the properties (model & energyLevel) it knows to look
        inside the current object. 
 
      
        Getters return/Display information 
        Setters update information 
 
        some notable advantages of using getter/setter methods:- 
 
        Getters can perform an action on the data when getting a property. 
        Getters can return different values using conditionals. 
        In a getter, we can access the properties of the calling object using this. 
        The functionality of our code may be easier for other developers to understand. 
        Another thing to keep in mind when using getter (and setter) methods is that properties cannot
        share the same name as the getter/setter function. If we do so, then calling the method
        will result in an infinite call stack error. 
        One workaround is to add an underscore before the property name like I did in the example below. 
 
        (Use GET and SET commands) 
 
        NOTE 
          Even though the getter looks like a function command when calling them in your code
          you DO NOT include the ( ) (opening/closing round brackets) like you would for a function.  
 
        const person = { 
 
             _firstName: 'John', 
             _lastName: 'Doe', 
 
             get  firstName() { 
 
                if (this._firstName){ 
                   return `${this._firstName}`; 
                } else { 
                   return 'Missing a first name.'; 
                } 
             }, 
 
             set  firstName(name) { 
 
                if (typeof(name)==="string"){ 
                   this._firstName = name; 
                } else { 
                   return "Invalid First Name!"; 
                } 
             }, 
 
             get  lastName() { 
 
                if (this._lastName){ 
                   return `${this._lastName}`; 
                } else { 
                   return 'Missing a last name.'; 
                } 
             }, 
 
             set  lastName(name) { 
 
                if (typeof(name)==="string"){ 
                   this._lastName = name; 
                } else { 
                   return "Invalid Last Name!"; 
                } 
             }, 
 
             get  fullName() { 
 
                if (this._firstName && this._lastName){ 
                   return `${this._firstName} ${this._lastName}`; 
                } else { 
                   return 'Missing a first name or a last name.'; 
                } 
             } 
          } 
 
 
        // To call the getter method  
        person.fullName;    // will give the value 'John Doe' 
        (Note there are no round brackets Eg...
          NOT person.fullName() like there would normally be for a function) 
           
 
        // To call the setter method  
        person.firstName = "Gary";    // will set _firstName to be 'Gary' 
        (Note there are no round brackets (and it uses the = sign, Eg...
          NOT person.firstName("Gary") like I would have expected for a function) 
           
 
        // To call the setter method  
        person.lastName = "Kirby";    // will set _lastName to be 'Kirby' 
 
        So now when you call the getter for fullName...  
        person.fullName;    // will give the value 'Gary Kirby' 
         
 
      
        You can also use a technique called 'Destructured Assignment' 
        
        Once the object (vampire) has been created you would then need to access the properties. 
 
        const creature = { 
             residence: 'Transylvania', 
             preferences: { 
                day: 'stay inside', 
                night: 'satisfy appetite' 
             } 
          };  
 
        And then when you want to retrieve, for example, the property 'residence' 
        the 'normal' way of doing things could look like this... 
 
        const residence = creature.residence; 
          console.log(residence);     // Prints 'Transylvania' 
 
        But the 'Destructured' way would be... 
        const { residence } = creature; 
          console.log(residence);     // Prints 'Transylvania' 
 
        and to read the creature.preferences.day property value you would say... 
        var { day } = creature.preferences; 
 
 
        
        //Factory Function - A function that can be called over and again to create objects 
        
          function createCircle(radius) { 
             return { 
                radius, 
                draw() { 
                   return `Circle was drawn with a radius of: ${radius}`; 
                } 
             }; 
          } 
 
          const circle1 = createCircle(20); 
          console.log(circle1.draw());
         
 
         
 
        Compared to the LongHand version (on the right pane)... 
 
        You don't need the radius: radius, if the parameter and the property
        name are going to be the same (just radius,) will do and Javascript
        will give it the property name of 'radius' automatically. 
 
        When creating a function called 'draw' you don't need to specify draw(): function() {} as
        JavaScript will know it's a function if you just tell it draw() {} ... 
        Note a normal way of creating a function outside of an object is 
          function draw() {} 
          so it is very much the same but you are dropping
          the word 'function'
 
      
        //Factory Function - A function that can be called over and again to create objects 
        
          function createCircle(radius) { 
             return { 
                radius: radius, 
                draw: function() { 
                   return `Circle was drawn with a radius of: ${radius}`; 
                } 
             }; 
          } 
 
          const circle1 = createCircle(20); 
          console.log(circle1); 
          const circle2 = createCircle(30); 
          const circle3 = createCircle(40); 
          etc... 
         
 
         
 
 
        NOTE... 
        The return bit in 'createCircle' has { } which means it is returning an Object with the
        property radius and a method draw() ... 
        ...this way when it is called I am
        making the variables circle1, circle2 & circle3 all Objects with the same properties & methods.