Learn JavaScript OOP: A primer for web development

May 23, 2019 - 10 min read
Educative
editor-page-cover

JavaScript may not be what comes to mind when someone mentions an OOP language, but the fact is it has great support for OOP - it just has its intricacies that need to be understood first. If you’re coding in JavaScript, getting familiar with OOP principles can make your life easier for a few reasons:

  • It’s easier to debug your code when you use objects and classes.
  • You’re able to use techniques like encapsulation and inheritance.
  • You’ll have an easier time getting hired on a team using OOP principles for their code.

Here, you’ll learn the basics of Object-oriented JavaScript in ES5 and ES6 so that you can see the comparisons and how JavaScript has trended towards an OOP style.

Today we will cover:



Take your JavaScript code to the next level

Learn to write cleaner, more modular, and scalable code with OOP principles.

Learn OOP in JavaScript



What is OOP (Object-Oriented Programming)?

If you’re familiar with other languages such as C# and Java, then you’ve probably heard the term Object-Oriented Programming (OOP).

Object-oriented programming is a style of programming, not a tool, which is why even though it’s an older style, it’s still very popular and widely used. This style involves breaking a program into segments of objects that can communicate with each other.

Each object is defined by its own set of properties, which can then be accessed and modified through various operations.

widget

The above illustration is a real-world example of an employee record where each employee can be considered an “object”, and since every employee has a name, age, and designation, these can be considered the properties of that employee.


OOP in JavaScript (ES5)

OOP in JavaScript works differently than in other languages. So, if you’re familiar with OOP in other languages it’s important you put that knowledge aside for now since holding on to those concepts might confuse you.

You’ve probably seen that other languages such as C++, Java, and C#, use the keyword class to define a class. A class has properties and methods in it for every instance of that class. In this case, class acts as a blueprint for the object.

JavaScript differs from other languages because you can implement OOP without the use of classes (more on this later). Before introducing its ES2015 version, JavaScript still relied on prototype-based programming. In this programming style, the object encapsulates the properties, i.e., its methods and data, instead of a class.

You can add new properties to this object at any time. So now, an object can be an individual instead of being an instance of the class, meaning if you want an object you easily just create one without having to create a class first.

widget

Both Prototype-based and Class-based OOP have their advantages and disadvantages. Prototype-based is more straightforward as you don’t need to create a blueprint beforehand which requires pre-planning about the sort of properties required before creating an object.

Since no class needs to be made, you can create the object directly. This also offers flexibility; hence, any changes to the objects can easily and quickly be made while they’re being used.

While all these advantages exist in Prototype-based programming, there is a higher risk of incorrectness as abrupt changes can easily be made. Whereas in the Class-based approach, the blueprints layout a plan beforehand, decreasing the chances of bugs arising.


Objects in JavaScript

Objects are a major part of JavaScript, as almost everything in it is an object. For example, functions, arrays, regular expressions, dates, and even data types like boolean and strings, if declared with the keyword new, can be considered a javascript object.

What is an object?

In real-life, objects are found everywhere, so these real-life scenarios can also be mapped into object-oriented code.

Let’s take a look at an example of how Objects are used. Assume you have three shapes which you need to find the area of: square, rectangle and circle. If you were to write code that would calculate the area of each, what would you do?

In an OOP style, you’d convert the code by creating objects for each shape: square, rectangle, and circle. Here, each object has its own set of properties which include:

  • Data values
  • Functions
svg viewer
Properties of the objects

We need the length, width, and the radius. These values will be encapsulated in the object of that particular shape. Similarly, a function to calculate the area will also be required. This will also be encapsulated in the object as a part of its properties.

svg viewer

How to create an object literal

An object literal can be created:

  • Using the figure brackets {...} in the declaration.
  • Using the new keyword.
  • Based on an existing object by using the create() method.

All of these approaches do exactly the same thing. Here’s what the syntax looks like:

Using figure brackets

var objectName = { 
 
 //properties defined
 propertyName1 : propertyValue1,
 propertyName2 : propertyValue2,
 functionName() {}
 
}

Using the new keyword

var objectName = new Object()

Using the create() method

var newObjectName = Object.create(existingObjectName)

Useful keywords: Get, Set, This

Get: The get keyword will bind an object property to a function. When this property is looked up now the getter function is called. The return value of the getter function determines which property is returned.

Set: The set syntax binds an object property to a function to be called when there is an attempt to set that property.

This: The this keyword refers to an object so that you can access the properties within an object. It can also be used to set the value of a property within an object.


Keep the learning going.

Learn OOP concepts in JavaScript without scrubbing through videos or documentation. Educative’s text-based courses are easy to skim and feature live coding environments, making learning quick and efficient.

Learn Object-Oriented Programming in JavaScript



Accessing properties of an object

There are various ways to access object properties. Outlined are a couple of popular ways, but you can also iterate over object properties using the for..in loop and you can also access properties of a nested loop. To implement this all that is required is to use the dot operator, but you’ll need to add one additional dot.


Dot operator

The dot operator is also useful for setting and deleting properties. In JavaScript, an object literal can be accessed using the dot operator. To access any property, the name of the object should be mentioned first, followed by the dot operator, and then the name of the property encapsulated in that object.

Here we can see the syntax of the dot operator:

objectName.functionName()

Here’s an example of how to access properties using the dot operator:

Here’s an example of how to access properties using the dot operator:

//creating an object named shape

var shape = {
 //defining properties of the object
 //setting data values
 name : 'square',
 sides : 4

}

//accessing the properties using the dot operator
console.log("Name is:", shape.name) //using dot operator to access "name"
console.log("Number of sides are:", shape.sides) //using dot operator to access "sides

Using square brackets

Another method to access values is by using the square brackets [ ]. The name of the property to be accessed is written inside the square brackets as a string. Using square brackets is also useful for setting and deleting properties.

Here we can see the syntax of the square brackets method:

objectName['functionName']()

Here’s an example of how to access properties using square brackets:

//creating an object named shape

var shape = {
 //defining properties of the object
 //setting data values
 name : 'square',
 sides : 4

}

//accessing the properties using square brackets
console.log("Name is:", shape['name']) // to access "name"
console.log("Number of sides are:", shape['sides']) // to access "sides"

Functions as objects

Constructor functions

Functions are also objects in JavaScript. This is because just like objects, they have their own properties and methods. Functions can be used to construct objects as well, and these types of functions are known as constructor functions.

Constructor functions essentially eliminate the need to create separate object literals for similar tasks. They are useful because you’ll often come across situations in which you don’t know how many objects you will be creating; constructors provide the means to create as many objects as you need in an effective way.

Here is the syntax for implementing the constructor function:

function FunctionName(parameter1, parameter2,...){
   //all the properties of the object are initialized here
   //functions to be provided by objects are defined here
}

As can be seen from above:

  • The keyword function is used to define the function.
  • The constructor function name should be capitalized just like FunctionName in the above snippet.
  • The body of this function is basically the constructor part of the function as it initializes the properties by setting them equal to the respective parameters being passed into the function.

Here is an example of a constructor function:

function Employee(_name, _age, _designation){
  this.name = _name
  this.age = _age
  this.designation = _designation
}

Note that all the objects created from Employee will contain the properties name, age, and designation, where the keyword this can assign specific values even though they’re part of the same property.


Prototype objects

Prototype objects are a simpler approach for adding new methods/properties to a constructor function.

Aside from the properties that you create, there is an additional hidden property known as [[Prototype]] property that is present inside every object created from a constructor function. The prototype property either points to another object or is null. Here is an example of using the Prototype property:

//Shape object

var Shape={
 name: 'Rectangle',
 sides: 4
}

//Rectangle object
var Rectangle = {
 length: 3,
 width: 5
}

//setting [[Prototype]] of Rectangle equal to Shape
Rectangle.__proto__ = Shape

//creating an object instance using Shape and Rectangle
console.log("Name of shape is:",Rectangle.name)
console.log("Number of sides are",Rectangle.sides)
console.log("Length is:",Rectangle.length)
console.log("Width is:",Rectangle.width)

Here we can see that when the prototype property of Rectangle is set to Shape, it is able to access all the properties in Shape. If a property is not found in the object, such as the name property is not found in Rectangle, JavaScript will automatically take it from the prototype of that object, Shape. This is known as prototypal inheritance where lines 20 and 21, are known as inherited properties; this is based on the concept of prototype chaining.


Object-oriented JavaScript in ES6

JavaScript ES6 offers some new features as well as improvements. One of those improvements that is the introduction of the keyword class. You can explore all the other nuances of ES6 here

Whereas in JavaScript ES5, function constructors were used to implement the concept of classes. However, in the ES6 version, the class keyword is used which cleans up the syntax for implementing the same concept, making it easier to understand.


Declaring a class in JavaScript ES6

The syntax is as follows:

class ClassName {
  constructor() {
    //initializing class properties
  }
  //class methods defined
}

One of the differences between the constructor function and class-based implementation is that, in the former, the body of the function acts as the constructor, where all the properties are defined, whereas, in the latter, there is a separate constructor function defined inside the class used to initialize the properties.


Creating an object instance from a class

Here we can see an example of how to create an object instance from a class:

//creating a class named employee
class employee{
 //creating the constructor function
 constructor(name,age,designation){
   //all properties defined as they were in the constructor function
   this.name = name
   this.age = age
   this.designation = designation
   this.displayName = function() {
     console.log("Name is:",this.name)
   }
 }
}

//creating an object instance named "employeeObj"
var employeeObj = new employee('Joe',22,'Developer')
//displaying the properties of employeeObj
employeeObj.displayName()
console.log("Age is",employeeObj.age)
console.log("Designation is:",employeeObj.designation)

Since employee is a constructor function itself, the method to create an object instance from a class is exactly the same as that in the ES5 version. The new keyword is used to initialize a new object, employeeObj. The constructor method then runs for this object assigning the values passed into it to the properties.


Defining methods in a class

Whenever a method is declared inside a class, it is defined on the prototype of that class. Meaning, whenever an object instance accesses it, it gets taken from the respective class’s prototype.

Here is an example:

//creating a class named employee
class employee{
 //creating the constructor function
 constructor(name,age,designation){
   //all properties defined as they were in the constructor function
   this.name = name
   this.age = age
   this.designation = designation
   this.displayName = function() {
     console.log("Name is:",this.name)
   }
 }
 //defining methods in a class
 //getAge method returning the age of the current object
 getAge(){
   return this.age
 }
}

Here’s what’s happening in the code above:

  • The getAge function is being defined outside of constructor function in line 15.
  • All such methods are stored in the prototype object of employee.
  • So, a new object, such as employeeObj, has access to all the methods defined in the class.
  • When called by employeeObj the method getAge is taken from employee.prototype.

What to learn next

Although JavaScript may not be considered an OOP language, the use of version ES6 (because of the use of classes) will give you a feel of what it’s like to code in a more traditional OOP programming language such as C/C++. The major differences between ES5 and ES6 is the addition and clean-up of syntaxes.

There is much more to learn, such as:

  • Static methods
  • Protecting properties
  • Data encapsulation
  • Mixins
  • and more

If you’re interested in going into more detail, you can learn all the essentials with Learn OOP in JavaScript. You’ll build up to more advanced concepts such as prototypal inheritance, prototype chaining, method overriding, and mixins.


Continue reading about JavaScript and OOP


WRITTEN BYEducative

Join a community of 500,000 monthly readers. A free, bi-monthly email with a roundup of Educative's top articles and coding tips.