OOP in JS: Object Basics


Object-Oriented Programming (OOP) is a popular programming paradigm that allows us a way to structure and maintain complex code.

Unlike other programming languages that use class-based object orientation, JavaScript uses prototype-based object orientation. This difference may be a source of confustion for developers coming from a class-based language, especially when using the “syntactical sugar” of the class keyword and the results don’t turn out quite as expected.

In this series, we’ll aim to cover the following things:

  • The Prototype Chain: the “under the hood” feature of JavaScript enables us to emulate OOP.
  • The this, new, and class keywords which allow us to automate our object and method creation.

But before we get to that, let’s take a look at objects themselves and how we can go about creating and using them, at a very basic level.

Creating Objects

Objects can be created in a few different ways.

  1. The Object() constructor (new Object()): const coffee = new Object();
  2. The Object.create() method: const coffee = Object.create();
  3. The Object Literal / Object Initializer notation: const coffee = {}

Properties & Methods

Creating an empty object isn’t always the most useful thing. In most cases, we’ll want to add properties and/or methods to that object. To do so, we can use Property Accessors.

If we create an object with the Object Literal approach, we can add properties directly on the object when we define it:

const coffee = {
    type: 'Ristretto',
    ingredients: ['espresso'],
    origin: 'Italy',
    description: 'A short shot of concentrated espresso.'
};

We can also add properties to an object that we’ve created via the dot notation:

const coffee = Object.create();

coffee.type = 'Ristretto';
coffee.ingredients = ['espresso'];
coffee.origin = 'Italy';
coffee.description = 'A short shot of concentrated espresso.';

This works regardless of which above approach we take to initially define the object.

We can store any type of data as properties on our object – even other objects. When a function is stored as a property on an object it is referred to as a “method”.

const coffee = {
    type: 'Ristretto',
    ingredients: ['espresso'],
    origin: 'Italy',
    description: 'A short shot of concentrated espresso.',
    brew: function() {
        console.log( `Your Ristretto will be ready in 5 minutes!` );
    }
};

Property Accessors

Once we have an object with all of the data that we want stored in it, we’ll need a way to access (and/or add to) that data.

Per MDN, “property accessors provide access to an object’s properties by using the dot notation or the bracket notation”.

Dot Notation

In addition to defining properties via the dot notation, as we saw above, we can also use it to access existing properties on an object:

coffee.type; // 'Riesretto

When working with dot notation, property identifiers can only be alphanumeric, with the exception of _ and $. Also properties can not start with a number.

Bracket Notation

The bracket notation is similar to accessing an index on an array – or an element in an associative array, if you’re familiar with that concept from another language:

coffee['description']; // 'A short shot of concentrated espresso.'

When working with bracket notation, property identifiers have to be a string. Unlike with dot notation, variables may also be used as long as the variable resolves to a string. This also means that they can include any characters – including spaces.

Overall, dot notation is much eaiser to read than bracket notation and will probably be what you see most often used. However, bracket notation is still very useful in scenarios where you need to work around those naming limitations in dot notation. For example:

const eleven = {
    '11' = 'eleven',
}

eleven.11; // this will result in a SyntaxError.
eleven['11']; // this will output 'eleven', as expected.

What’s Next?

Now that we’ve gone over the very basics of objects in JavaScript, we can move on to discuss the Prototype Chain (in a future article) and how we can use it to work with objects in an object-oriented paradigm.