Home

Objects and Properties

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


Different ways to create an object:

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).

Top

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)


Top

Example 1 - Constructors

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)


Top

Example 2

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);
}

A little more about THIS.

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.

Top

using GETTERS & SETTERS

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;






Now what if we want another object that has the properties of creature but with a few additional properties.
Object.assign() could be a good method to use as it combines one or more objects to a 'target' object.
eg...
Object.assign(target, source, source, source etc);

So...we could create our new object with just the additional properties in it and the use the .assign command to inherit the properties in 'creature'.

Create new object called vampire
const vampire = {
   name: 'Dracula',
   skill: 'Change into Bat'
};


inherit properties of creature and include them on the target object 'vampire'
Object.assign(vampire, creature);

Once assigned the properties & values of vampire will be...



And to display the values in red I had to do the following...
(it reads all properties & displays it but if it finds a property that is an object it reads through that to find those properties too)

var txt="";
for (x in vampire) {
   if (typeof(vampire[x])!=="object") {
      txt += x + ": " + vampire[x] + "
";    } else {
      
//It's another object so read thru this too
      for (y in vampire[x]) {
         txt += x + "." + y + ": " + vampire[x][y] + "
";
      }
   }
}
document.getElementById("assignIt").innerHTML = txt;

Top

Factory Function example (using shorthand version)

//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 example (using longhand version)

//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.

Top