If you’ve come to JavaScript from a language like Java, you may be familiar with terms like Object Oriented Programming (OOP), classes, and inheritance. However, if you’re like me and new to the world of actual OOP languages like C++, Java, and C#, you might need some clarification on what OOP means in programming. Similarly, you may be wondering what Procedural Programming is and where JavaScript fits into the picture. Fear not, as in this article, we will explore these concepts together in a beginner-friendly manner. Whether you’re a seasoned programmer or just starting out, this article aims to explain OOP and procedural programming in a way that everyone can understand.

What is Object Oriented Programming (OOP)?

OOP is the programming paradigm in which data is everything. The program is divided into many small entities called Objects along with associated methods. Objects hold the data, along with attached procedures to work on that data. In this widely used programming approach, data is the most important thing. There are ways to store, manipulate, and make data private, with access specifiers like private, public, protected, etc.

Languages: Java, C++, C#

What is Procedural Programming?

Procedural programming is a programming paradigm that involves breaking down a program into a set of procedures, also known as functions or subroutines, that can be called in a specific sequence to perform a particular task. In procedural programming, the focus is on procedures, and data is often shared between procedures by passing it as arguments.

Languages: Pascal, Basic, FORTRAN

Understanding the Programming Paradigms of JavaScript: OOP vs. Procedural Programming

JavaScript is a multi-paradigm programming language, which means that it supports multiple programming paradigms, including object-oriented programming (OOP) and procedural programming.

JavaScript’s support for OOP is based on class inheritance and object prototypes. It has a class keyword that allows for the creation of classes, which can be used to define objects. It also supports inheritance through the use of object prototypes, which allow objects to inherit properties and methods from other objects. This means that JavaScript can be used as an OOP language.

On the other hand, JavaScript’s support for procedural programming is based on functions, which can be used to organize code into smaller, reusable blocks. Data is passed to functions as arguments, and functions can return values. This means that JavaScript can also be used as a procedural programming language.

In summary, JavaScript supports both OOP and procedural programming paradigms. The choice of which paradigm to use depends on the specific needs of the program being developed.

Let's discuss Object Oriented Programming in JavaScript in detail.

Object Orient Programming (OOP) in JavaScript

JavaScript supports OOP through prototypes, which are essentially objects that serve as a blueprint for other objects. Prototypes in JavaScript allow for inheritance, encapsulation, and polymorphism, which are key principles of OOP. Well, you can also leverage JavaScript OOP using ES6 Classes introduced to mimic OOP classic behavior found abundantly in true class-based OOP languages like Java, C#, etc.

Prototypal Object Orient Programming (OOP) in JavaScript

JavaScript is not a pure class-based OOP language, as it doesn’t use classes natively for inheritance. Instead, JavaScript uses prototypal inheritance. Objects are created based on prototypes which serve as blueprints for the objects. These prototypes or blueprints are also objects. In short, you use objects to create new objects using something called prototypal inheritance.

In Prototypal OOP, objects inherit properties and behaviors from their prototypes. Consider this example below, we can create a new object from the prototype object using Object.create() method;

Where does this nameproperty on the child object come from? Well, it comes from its prototype, which in our case is the parent object.

Objects prototype can be accessed using the __proto__ property.

Prototype Chaining

Why stop here? Let’s create another object using the same method but now we will use the child as a prototype.

You know how to do that, right? Exactly, using the Object.create() method.

You can trace a series of prototypes chain in a sequence we set them. Let’s do the math now, object parent is inheriting from the default object prototype, the child is inheriting from the parent. Right? Almost. a child is inheriting from the parent and default object prototype. And similarly, the grandchild object inherits from all of them down the chain. You don’t believe me, right? Have a look:

You can see, the grandchild itself only contains city property, then where are the rest of the properties coming from, inheritance mate, inheritance.

Own Properties vs Inherited Properties

You might be unaware of the face so far that object properties can be of two types. Own properties and the properties object inherits from its prototypes. The above example grandchild only has one property, city and it inherits the rest of them from its prototypes down the chain. You see, no error there. This is because the JavaScript parser looks for the property or method in the object, and in case not found starts to look down the prototype chain one by one. Due to this fact, you can overwrite certain properties in an object.

Methods of Object Oriented Programming in JavaScript

In JavaScript, there are several ways to implement Object-Oriented Programming (OOP). The three main approaches are:

Constructor Functions and Prototypes:

This is the most traditional way of implementing OOP in JavaScript. Constructor functions are used to create new instances of an object and prototypes are used to share methods and properties among instances.

Factory Functions:

This approach involves creating functions that return new objects. Factory functions can be used to create multiple instances of an object with different properties and methods. This approach is useful when we want to create objects with different configurations.

The factory function looks quite similar to the Constructor function with a couple of differences;

  1. You have to explicitly return a configured object.
  2. You cannot set a prototype object

ES6 Classes (Pseudo class-based OPP approach)

With the introduction of ES6 (ECMAScript 2015), JavaScript now has a class syntax that is similar to traditional OOP languages. But, under the hood, JavaScript classes still use prototypes for inheritance. Classes provide a way to define a blueprint for creating objects with properties and methods.

The syntax for creating a class in ES6 is as follows:

Now have a look at this example, we create a Class that defines a set of properties and methods that the objects created from it will have.

Now if you try to inspect one of these created objects;

You can see that Object has been created using the blueprint of the Car class. And you can also see that method getFullDescription is also present in the prototype of every created object.

ES6 Class Features Compared to Traditional Class-Based Approaches

We have already discussed a couple of features of class-based OOP in Java above, Inheritance and Encapsulation. Let’s try to compare it with the Class-based approach of JavaScript.

Inheritance

ES6 classes also support inheritance, which allows you to create a new class based on an existing class. This is useful when you want to reuse code from an existing class or create a more specialized class. To inherit from a class, you use the extends keyword. Here’s an example:

Let’s create a sub-class for Sports cars from the above Car class;

As you can see, the created object ferrari is an instance of both the Car and SportsCar class as SportsCar inherits from the Car instance.

This was Inheritance, now let’s get to Encapsulation which is another important feature in OOP.

Encapsulation

Encapsulation is a fundamental concept in object-oriented programming, adding an additional layer of privacy, and controlling access to that object’s properties and methods from outside.

In JavaScript ES6 classes, encapsulation is achieved through the use of private, protected, and public access modifiers. These access modifiers control the visibility and accessibility of properties and methods within a class.

Private properties and methods: Private properties and methods are only accessible within the class in which they are defined. They are denoted with the # symbol in front of their names. Here’s an example:

Protected properties and methods: Protected properties and methods are accessible within the class in which they are defined, as well as any subclasses that inherit from that class. They are denoted with the _ symbol in front of their names. Here’s an example:

Public properties and methods: Public properties and methods are accessible from anywhere, both within and outside the class. They are not denoted with any symbol. Here’s an example:

In the above example, the width and height properties and the getArea method are public and can be accessed from anywhere.

Wrapping Up

I hope you found this guide helpful. If you have any questions or found something confusing, please let me know so I can improve future guides. If you noticed any mistakes, please don’t hesitate to point them out so I can correct them for future readers.

If you’re interested in learning more about the MERN stack, I regularly post guides on this topic, so be sure to follow me for updates.

Thank you for reading and stay safe. Take care! ❤️”