start learning
Image 1
447906036355947

JavaScript Object-Oriented Programming (OOP)

JavaScript Object-Oriented Programming (OOP) is a programming paradigm that focuses on organizing code around objects that contain both data and behavior. In JavaScript, objects are created using constructor functions, classes (introduced in ES6), or object literals.

In OOP, objects are instances of classes or blueprints that define their structure and behavior. They encapsulate related data and methods, allowing for modular and reusable code. Here are some key concepts in JavaScript OOP:

  1. Classes: A class is a blueprint or template for creating objects. It defines the properties and methods that objects of that class will have. In JavaScript, classes can be defined using constructor functions or the class syntax introduced in ES6.
  2. Objects: Objects are instances of classes or constructor functions. They represent individual entities with their own unique data and behavior. Objects can be created using the new keyword and the constructor function or class.
  3. Encapsulation : Encapsulation is the practice of bundling related data and methods into objects. It provides data privacy by controlling access to the internal state of an object. In JavaScript, you can achieve encapsulation through the use of closures, private variables, and the concept of public and private methods.
  4. Inheritance : Inheritance is a mechanism that allows objects to inherit properties and methods from a parent or superclass. It enables code reuse and promotes hierarchical relationships between classes. In JavaScript, prototype-based inheritance is used, where objects inherit from prototypes or other objects.
  5. Polymorphism : Polymorphism allows objects to take on different forms or behaviors while sharing a common interface. It allows you to use objects of different classes interchangeably based on their shared methods or properties.

By leveraging these OOP concepts in JavaScript, you can create modular, reusable, and maintainable code. OOP provides a way to organize code logically, promote code reuse, and create scalable applications.


Constructor Functions and Objects


// Define a constructor function 'Person' with two parameters: name and age
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Create instances of the 'Person' class and initialize with values
var person1 = new Person('Alias', 25);
var person2 = new Person('Bob', 30);

// Log the 'name' property of 'person1' and 'age' property of 'person2'
console.log(person1.name); // Output: Alias
console.log(person2.age); // Output: 30

In this example, the Person function acts as a constructor function. It defines properties (name and age) that will be assigned to objects created using the new keyword. person1 and person2 are two instances of the Person object, each with their own set of properties.



// Define a class 'Animal' with a constructor method
class Animal {
  constructor(name) {
    this.name = name;
  }

  // Define a method 'sayName' to log the name
  sayName() {
    console.log('My name is ' + this.name);
  }
}

// Define a class 'Dog' that extends 'Animal'
class Dog extends Animal {
  // Define a method 'bark' for the 'Dog' class
  bark() {
    console.log('HOW!');
  }
}

// Create an instance of 'Dog' class with name 'BLOB'
const dog = new Dog('BLOB');

// Call the 'sayName' and 'bark' methods on 'dog'
dog.sayName(); // Output: My name is BLOB
dog.bark(); // Output: HOW!

In this example, we define two classes: Animal and Dog. The Dog class extends the Animal class using the extends keyword, enabling inheritance. The classes have constructor methods and additional methods like sayName() and bark(). We create an instance of the Dog class called dog and invoke its methods.
Check more examples of JavaScript OOP classes


Objects


// Create an object 'person' with properties and methods
const person = {
  name: 'Alias',
  age: 25,
  greet() {
    console.log('Hello, my name is ' + this.name);
  }
};

// Log the 'name' property of 'person'
console.log(person.name); // Output: Alias

// Call the 'greet' method on 'person'
person.greet(); // Output: Hello, my name is Alias

In this example, we create an object person using object literal syntax. It has properties (name and age) and a method (greet). We can access the object properties and invoke the method directly on the person object.


Prototype and Method Inheritance


// Define a constructor function 'Person' with a 'name' parameter
function Person(name) {
  this.name = name;
}

// Add a 'greet' method to the 'Person' prototype
Person.prototype.greet = function() {
  console.log('Hello, my name is ' + this.name);
};

// Define a constructor function 'Student' with 'name' and 'grade' parameters
function Student(name, grade) {
  // Call the 'Person' constructor within 'Student'
  Person.call(this, name);
  this.grade = grade;
}

// Set up the prototype chain for 'Student' and link it to 'Person' prototype
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// Create a 'student' object with name 'Alias' and grade '10'
var student = new Student('Alias', 10);

// Call the 'greet' method on the 'student' object
student.greet(); // Output: Hello, my name is Alias

In this example, we have two constructor functions, Person and Student. The Student constructor inherits from the Person constructor using Object.create . The greet method is defined on the Person.prototype and is inherited by the Student prototype. By calling student.greet() , we can invoke the greet method on the student object.


Encapsulation and Private Variables


// Define a constructor function 'Counter'
function Counter() {
  var count = 0;

  // Define an 'increment' method within 'Counter'
  this.increment = function() {
    count++;
    console.log('Count: ' + count);
  };

  // Define a 'decrement' method within 'Counter'
  this.decrement = function() {
    if (count > 0) {
      count--;
      console.log('Count: ' + count);
    }
  };
}

// Create an instance of 'Counter' named 'counter'
var counter = new Counter();

// Call the 'increment' and 'decrement' methods on 'counter'
counter.increment(); // Output: Count: 1
counter.decrement(); // Output: Count: 0

In this example, the Counter constructor function encapsulates the count variable within its scope. The increment and decrement methods are public methods that can access and modify the count variable. The count variable remains private and is not directly accessible from outside the Counter object.


Polymorphism

// Define a class 'Shape' with a 'calculateArea' method
class Shape {
  calculateArea() {
    console.log('Calculating area of the shape.');
  }
}

// Define a class 'Rectangle' that extends 'Shape'
class Rectangle extends Shape {
  calculateArea() {
    console.log('Calculating area of a rectangle.');
  }
}

// Define a class 'Circle' that extends 'Shape'
class Circle extends Shape {
  calculateArea() {
    console.log('Calculating area of a circle.');
  }
}

// Define a function 'calculateAreaOfShape' that takes a 'shape' as a parameter and calculates its area
function calculateAreaOfShape(shape) {
  shape.calculateArea();
}

// Create instances of 'Rectangle' and 'Circle' classes
const rectangle = new Rectangle();
const circle = new Circle();

// Call 'calculateAreaOfShape' function for 'rectangle' and 'circle' objects
calculateAreaOfShape(rectangle); // Output: Calculating area of a rectangle.
calculateAreaOfShape(circle); // Output: Calculating area of a circle.

In this example, we have a Shape class and two subclasses: Rectangle and Circle. Each class has a calculateArea method, which is overridden in the subclasses with their specific implementation. The calculateAreaOfShape function takes a shape object as an argument and calls its calculateArea method. By passing different shape objects, we achieve polymorphism as the appropriate method is called based on the object's type.


Feel free to copy the code and experiment with our JAVASCRIPT COMPILER


Output: