Recommended Reading: Chapter 6 in the JavaScript book

Basics of objects

A JavaScript object is a bundle of properties. Each property has a name and a value. For example, here is a JavaScript object that contains information about a menu item at a cafe:

{name:"Tuna Melt",meal:"Lunch",price:4.95}

Unlike other object oriented languages where you have to start by declaring a class, you can just create JavaScript objects on the fly:

let item = {name:"Tuna Melt",meal:"Lunch",price:4.95};

To access the individual properties in an object, we use the usual member syntax.

total = total + item.price;

You can add new properties to an object by simply assigning a value to a new property name.

item.description = "Canned tuna and melted cheese";

You can also remove properties from an object via the delete statement.

delete item.meal;

Methods

Besides holding data values, properties in an object can also store methods that act on the object.

Here is a concrete example. In this example I am setting up a simple object that represents a rectangle. The rectangle has width and height properties, along with a getArea method that can compute and return the area of the rectangle object.

let rect = {width:200,height:300,
            getArea:()=>{ return width*height;}};

To invoke the method that computes the area we use this syntax:

let area = rect.getArea();

Methods can access the properties of the object they are attached to by using the property names as variable names. In this example the getArea function needs to access the width and height properties of the object it is attached to, so it just uses those property names to access the data it needs.

The technique that I used in the example above to attach a method to an object works just fine for a single object, but quickly becomes tedious to implement if we are dealing with multiple objects of the same type. For example, here is some code that sets up three separate rectangles and gives each one a getArea method.

let rectangles = [{width:100,height:300,
                  getArea:()=>{ return width*height;}},
                  {width:75,height:200,
                  getArea:()=>{ return width*height;}},
                  {width:200,height:50,
                  getArea:()=>{ return width*height;}}];

To eliminate the redundancy in defining the method, we can instead use this approach:

function area() {
  return width*height;
}

let rectangles = [{width:100,height:300,getArea:area},
                  {width:75,height:200,getArea:area},
                  {width:200,height:50,getArea:area}];

The area function we have set up here is designed to be attached to a rectangle object as a method. This function only makes sense when used as a method, because the function makes use of the properties width and height that only make sense when used in the context of a rectangle object that has those properties. To help make it explicit that width and height are properties of an object, we can use the following syntax instead:

function area() {
  return this.width*this.height;
}

let rectangles = [{width:100,height:300,getArea:area},
                  {width:75,height:200,getArea:area},
                  {width:200,height:50,getArea:area}];

The keyword this when used in the context of a method refers to the object the method is attached to. The area function computes the desired area by getting the width property that belongs to this object and the height property that belongs to this object.