Getting Started with Object-Oriented Programming in JavaScript ( Part 1 )
Object-Oriented Programming (OOP) in JavaScript introduces a structured way to create and manage complex applications. Using concepts like classes, objects, inheritance, and encapsulation, JavaScript allows developers to model real-world entities and their interactions efficiently.
Classes and Objects
In object-oriented programming, a class is a blueprint for creating objects. These objects are real instances of the class. For example, if Product
is a class, Poco F4
or Lenovo IdeaPad
are objects created from this class. The class defines properties (data members) and behaviors (member functions) of the objects.
Properties and Behaviors
Properties are the attributes that the class can have. For example, a Product
class can have properties like name
, description
, price
, and rating
.
Behaviors are the actions that the class can perform. For example, a Product
class can have behaviors like buying a product, displaying a product, or updating a product.
Creating a Class in JavaScript
In JavaScript, you can define a class using the class
keyword. Inside the class, you define properties and behaviors. Properties are initialized inside the constructor, a special function called when creating a new instance of the class.
Constructors in JavaScript vs. Other Languages
In object-oriented programming languages like Java or C++, constructors are special methods used to initialize new objects. These constructors have the same name as the class. However, in JavaScript, we use the constructor
keyword to define a constructor function within a class.
Initializing Data Members
To define and initialize data members in JavaScript, we use the constructor
function. The this
keyword is used to bind these data members to the new object being created.
Here's how you can create a class with a constructor in JavaScript:
class Product {
constructor(n, p) {
//constructor function to create new real life instances called as object
//When we create an object this constructor is the first function that gets called
this.name = n;
this.price = p;
}
//member function
displayProduct() {}
buyProduct() {}
}
Constructor Function: The
constructor
function is called automatically when a new object is created. It initializes the object's properties.this Keyword: The
this
keyword inside the constructor refers to the new object being created. It is used to set the properties of the object.Member Functions: Functions defined inside a class that operates on the data members of the class. They can be called on objects created from the class.
Creating a Real-Life Object
To create a real-life object from a class in JavaScript, we use the new
keyword. This keyword calls the constructor function and initializes the object's properties with the provided parameters.
Here's an example:
let iphone = new Product("iPhone 14", 70000);
In this example, new Product("iPhone 14", 70000)
calls the constructor function of the Product
class with two parameters: "iPhone 14"
and 70000
. The constructor function then initializes the object's properties based on these parameters.
Constructor Function Execution
When we call new Product("iPhone 14", 70000)
, the following happens:
Calling the Constructor: The
new
keyword invokes the constructor function of theProduct
class.Parameter Assignment: The parameters
"iPhone 14"
and70000
are passed to the constructor function.Object Creation: The constructor function creates a new object and initializes its properties using the provided parameters.
Data Member Declaration
In many programming languages, data members (properties) are declared outside the constructor function. However, in JavaScript, we declare and initialize data members inside the constructor function using the this
keyword.
Here’s how it looks in JavaScript:
class Product {
constructor(name, price) {
// The constructor function initializes new objects.
// 'name' and 'price' are initialized as properties of the new object.
this.name = name;
this.price = price;
}
// Member functions
displayProduct() {
console.log(this.name, this.price);
}
buyProduct() {
// Logic to buy the product
}
}
// Creating a new object
let iphone = new Product("iPhone 14", 70000);
We can access the above data members inside the member function using this
keyword.
//member function
displayProduct() {
console.log(this.name, this.price);
}
buyProduct() {}
We can call the member function like this.
iphone.displayProduct();
If we don't use this
keyword, it won't recognize it as a data member.
Also, a class can have only one constructor.
Understanding the this
Keyword in JavaScript
The behavior of the this
keyword in JavaScript is different from that in languages like C++ or Java. In JavaScript, this
refers to the context from where the function or class is called, known as the calling site.
The new
Keyword and Its Role
To understand how this
works in JavaScript, it's essential to first understand the new
keyword. While it may seem like new
is only used to call constructors, it does much more. The new
keyword can also be used with functions, not just classes.
Here's what happens when you use the new
keyword:
Creates a New Object:
- The
new
keyword creates a new, empty JavaScript object.
- The
Links the Object:
- It performs a process of linking (which we'll discuss later).
Assigns
this
:- The function is called with the
this
property set to the new object created in the first step.
- The function is called with the
Executes the Function:
The function runs, and
this
refers to the new object.If the function doesn't explicitly return an object, it returns
this
.
Example with a Function
function Product(name, price) {
this.name = name;
this.price = price;
return this;
}
const p1 = new Product("Poco F6", 40000);
console.log(p1);
When we call new Product("Poco F6", 40000)
, the following steps occur:
Creates a New Object:
- A new empty object is created.
Links the Object:
- (Linking details to be discussed later.)
Assigns
this
:this
inside theProduct
function refers to the new empty object.
Executes the Function:
The
Product
function runs, settingthis.name
to "Poco F6" andthis.price
to 40000.The function returns
this
, the new object with the properties set.
Function Example with new
When you define a function to act as a constructor and use the new
keyword, it creates a new instance of the object:
function Product(n, p) {
this.name = n;
this.price = p;
}
const p1 = new Product("iphone", 1000000);
console.log(p1); // Output: Product { name: 'iphone', price: 1000000 }
Function Example without new
If you call the same function without the new
keyword, it behaves as a regular function and this
refers to the global object (or undefined
in strict mode). Therefore, it won't create a new object:
function Product(n, p) {
this.name = n;
this.price = p;
}
const p1 = new Product("iphone", 1000000);
console.log(p1); // Output: Product { name: 'iphone', price: 1000000 }
const p2 = Product("Galaxy S3", 10000);
console.log(p2); // Output: undefined
Key Points
With
new
:Creates a new object.
Sets
this
to the new object.Returns the new object.
Without
new
:Calls the function as a regular function.
this
refers to the global object orundefined
.Does not create a new object.
Class Syntax
Unlike function-based syntax, class-based syntax always requires the new
keyword to create an instance:
class Product {
constructor(n, p) {
this.name = n;
this.price = p;
}
}
const p1 = new Product("iphone", 1000000);
console.log(p1); // Output: Product { name: 'iphone', price: 1000000 }
You cannot call a class constructor without new
:
const p2 = Product("Galaxy S3", 10000); // Throws an error
function Product(n, p) {
this.name = n;
this.price = p;
this.display = function () {
console.log(this.name, this.price);
};
}
const p1 = new Product("iphone", 1000000);
console.log(p1);
p1.display();
When p1.display()
is called, this
inside display
refers to p1
, allowing access to its properties.
In JavaScript, the behavior of the this
keyword differs between regular functions and arrow functions.
const obj = {
name: "Chandler",
display: function () {
console.log(this, "is the calling site");
},
};
//arrow function
const obj2 = {
name: "Ross",
display: () => {
console.log(this, "is the calling site");
},
};
obj.display();
obj2.display();
//output: { name: 'Chandler', display: [Function: display] } is the calling site
// {} is the calling site
- Regular Function:
const obj = {
name: "Chandler",
display: function () {
console.log(this, "is the calling site");
},
};
obj.display(); // Output: { name: 'Chandler', display: [Function: display] } is the calling site
Behavior: In the regular function
display
insideobj
,this
refers to the objectobj
itself.Output: When
obj.display()
is called, it prints{ name: 'Chandler', display: [Function: display] } is the calling site
.
- Arrow Function:
const obj2 = {
name: "Ross",
display: () => {
console.log(this, "is the calling site");
},
};
obj2.display(); // Output: {} is the calling site
Behavior: Arrow functions do not have their own
this
context. Instead, they inheritthis
from the surrounding lexical scope at the time the arrow function is created.Output: When
obj2.display()
is called,this
inside the arrow function does not refer toobj2
. Instead, it refers to the global object (orundefined
in strict mode), leading to the output{}
.
We've explored how classes serve as blueprints for objects, the role of constructors, and the special behavior of the this
keyword in both regular and arrow functions. Mastering these concepts will enhance your ability to create dynamic and efficient JavaScript applications.
Stay tuned for Part 2, where we'll delve deeper into more advanced topics such as inheritance, prototypes, and the modern features introduced in ES6 and beyond. Keep learning and coding!
Subscribe to my newsletter
Read articles from Nikhil Chauhan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by