A Beginner's Guide to OOP in JavaScript
The Object-Oriented Programming (OOP) paradigm has played a key role in software development for many years. JavaScript is a language that performs this paradigm, implementing OOP in a manner that sets it apart from other languages. If you’re new to programming or OOP, it could be tricky. This guide will take you through a step-by-step approach to explain how OOP works in JavaScript and provide examples of its use cases. By the end, you’ll have grasped the fundamentals of OOP in JavaScript and can begin using it.
What is Object Oriented Programming?
Object-Oriented Programming is a method of writing programs that make it easier to manage and organize. Instead of writing code in a long and confusing block, OOP allows us to break down code into smaller, more manageable parts called objects. These objects can store data and instructions for what to do with that data, making it easier to reuse the code and keep track of what’s going on with it.
Objects are basic data units used to store and manipulate data. Objects are defined by their properties, which are the characteristics that describe the object. In JavaScript, an object’s property is represented as key-value pair. The key is a string that represents the name of a property, while the value is the data stored in that property. Remember that an object can store several data types, such as strings, numbers, and even other objects.
To create an object in JavaScript, we first create a variable with curly brackets.
const person = {};
Then we assign key-value pairs to the object.
const person = {
name: "Bruce Wayne",
age: 30,
occupation: "Private Investigator",
};
In our person
object, the name
, age
, and occupation
keywords are the object’s properties (keys), while the values assigned to them are the property’s values.
Accessing Objects
This is a process of retrieving the data stored in an object. This is done by referencing the key attribute of an object. When we do so, we can access the value stored in that property. To perform this, we use one of the following notations.
- The Dot Notation: To access the property or method of an object using this notation, we write the object name, then a dot (.), and then the property we want to access.
Using our
person
object as an example, let’s access thename
property.
person.name;
Logging this to the console gives the value stored in the name
property.
- The Bracket Notation: To access the property or method of an object using this notation, we write the object name, then a pair of square brackets ([ ]), and the property we want to access in quotes.
person["name"];
Logging this to the console yields the same result as the Dot Notation.
Constructor Functions
These are special functions that can be used to create objects. They are used to create multiple instances of the same object with the same properties and methods. To create a constructor function, we use the following syntax. First, we create a regular function and pass in parameters.
const Person = function (name, age) {
};
Next, we call our function with the new
keyword. The new
keyword enables our function to become a constructor function.
const person1 = new Person("James Bond", 40);
This creates an instance of the Person
object and stores it in person1
. This process also sets the this
keyword on each instance we create. Keep in mind that the this
keyword points to the newly created object being constructed.
Next, we fill our newly created object with the parameters we passed when we created it.
const Person = function (name, age) {
this.name = name;
this.age = age;
};
Logging the person1
instance to the console now yields;
And with that, we’ve created our first object using a constructor function!
Adding methods to Constructor Functions
To add a method to a constructor function, we define that method in the constructor function. This way, all instance objects inherit that method when they’re created. For example, let’s add a method to our old constructor function.
const Person = function (name, age) {
this.name = name;
this.age = age;
this.calcBirthYear = function () {
return 2023 - this.age;
};
};
To get the result of this method, we call the calcBirthYear
method on our instance using the DOT notation.
person1.calcBirthYear();
Logging this to the console gives
There is yet a problem with this procedure. Each time we create an instance object, that object contains the calcBirthYear
method, which can affect our code’s performance.
The “this” Keyword
The this
keyword in JavaScript refers to an object executing a function. It indicates which object executes the method and represents the object to which it belongs. Using the DOT notation, we can use the this
keyword to refer to properties and methods of objects within those objects. It’s critical to understand that the value of this
is not constant and can change depending on how the function is called.
Session Replay for Developers
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.
Prototypal Inheritance
Prototypal inheritance is a mechanism that allows objects to inherit properties and methods from other objects. This means you can create new objects that share common properties and methods with existing objects. This makes creating new objects and reusing code easier since you can build on existing objects instead of writing new code from scratch for each new object.
How Prototypal Inheritance works
In JavaScript, every object has a prototype, a blueprint object used to create objects.
- An object’s prototype can be accessed using the
__proto__
property. - The prototype object allows other objects to inherit its properties and methods.
- When you try to access a property or method in an object, JavaScript first checks if it exists on the object itself. If it doesn’t, it checks the object’s prototype. If it still doesn’t exist, it checks the object’s prototype’s prototype. This connection of objects by prototype is called the
prototype chain
. This process continues until the property or method is found or the end of theprototype chain
is reached.
Sharing methods with Prototypal Inheritance
First, we recall our Person
constructor function.
const Person = function (name, age) {
this.name = name;
this.age = age;
};
Next, we use the prototype
property to add a method to our person object.
Person.prototype.calcBirthYear = function () {
return 2023 - this.age;
};
The prototype
property lets us add methods to the prototype of a constructor function and not the constructor function itself. This way, instances created from a constructor function do not contain the methods but can inherit them from their constructor function’s prototype.
Taking a look at the constructor function on the console gives;
As we can see, our calcBirthYear
method does not exist in the constructor function. But logging the prototype
of our constructor function yields a different result.
console.log(Person.prototype);
Our method exists in the constructor function’s prototype and can be inherited by instances of the constructor function.
Classes
Classes allow developers to create objects with specific properties and methods and act as a blueprint for creating objects with common characteristics.
To create a class in JavaScript, we use the class
keyword to declare a variable.
class PersonCl {};
Next, we specify a constructor function and pass in our parameters. This constructor function works the same way as the constructor function we’ve gone over previously.
class PersonCl {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
To create an object from the PersonCl
class, we call our new object with the new
keyword.
const bruce = new PersonCl("Bruce", 30);
Logging it to the console gives
Inheriting methods from Classes
Like in prototypal inheritance, objects can inherit methods from their parent class. To illustrate this, we create a method in our PersonCl
class.
class PersonCl {
constructor(name, age) {
this.name = name;
this.age = age;
}
calcBirthYear() {
return 2023 - this.age;
}
}
Then we pass that method to our instance object and log it to the console.
console.log(bruce.calcBirthYear());
It is important to note that when an object inherits a method from a class, that method does not exist on the object but on the prototype of that object. For further clarity, observe the image below.
As shown above, the calcBirthYear
function does not exist in the object we created but exists in the prototype of that object.
Conclusion
In conclusion, OOP is a fascinating topic that can take your JavaScript skills to the next level. From understanding objects and constructor functions to grasping the this
keyword and prototypal inheritance, this guide has covered all the essential elements of OOP. Let’s not forget the elegance of using classes in JavaScript, which allows you to inherit methods and write more efficient and organized code. So what are you waiting for? Grab your code editor, your favorite cup of coffee, and start using OOP in your projects!