Getting Started with Object-Oriented Programming in JavaScript ( Part 1 )

Nikhil ChauhanNikhil Chauhan
8 min read

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:

  1. Calling the Constructor: The new keyword invokes the constructor function of the Product class.

  2. Parameter Assignment: The parameters "iPhone 14" and 70000 are passed to the constructor function.

  3. 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:

  1. Creates a New Object:

    • The new keyword creates a new, empty JavaScript object.
  2. Links the Object:

    • It performs a process of linking (which we'll discuss later).
  3. Assigns this:

    • The function is called with the this property set to the new object created in the first step.
  4. 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:

  1. Creates a New Object:

    • A new empty object is created.
  2. Links the Object:

    • (Linking details to be discussed later.)
  3. Assigns this:

    • this inside the Product function refers to the new empty object.
  4. Executes the Function:

    • The Product function runs, setting this.name to "Poco F6" and this.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 or undefined.

    • 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
  1. 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 inside obj, this refers to the object obj itself.

  • Output: When obj.display() is called, it prints { name: 'Chandler', display: [Function: display] } is the calling site.

  1. 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 inherit this 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 to obj2. Instead, it refers to the global object (or undefined 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!

0
Subscribe to my newsletter

Read articles from Nikhil Chauhan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nikhil Chauhan
Nikhil Chauhan