Define a Constructor Function:
function Person(name, age) {
this.name = name;
this.age = age;
}
Add a Method to the Constructor Function's Prototype:
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
};
Create a New Object Using the Constructor Function:
const person1 = new Person("Alice", 30);
Call the Method on the Object:
person1.sayHello(); // Output: "Hello, my name is Alice and I'm 30 years old."
// Define a constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
// Add a method to the constructor function's prototype
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name + " and I'm " + this.age + " years old.");
};
// Create a new object using the constructor function
var person1 = new Person("Alice", 30);
// Call the method on the object
person1.sayHello(); // output: "Hello, my name is Alice and I'm 30 years old.
Object-Oriented Programming in JavaScript with Examples [Updated 2024]
Object-Oriented Programming (OOP) in JavaScript is a paradigm focused on objects rather than functions. Unlike procedural programming, which structures programs as a sequence of logical steps, OOP models complex systems as interactive objects.
This guide explores the core principles of OOP in JavaScript with practical examples.
-
Objects and Classes
- An object in JavaScript is a standalone entity with properties and a type.
const dog = { breed: 'Labrador', color: 'black', bark() { console.log('Woof!'); } }; dog.bark(); // Output: Woof!
- Classes, introduced in ES6, serve as templates for creating objects.
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } const animal = new Animal('Dog'); animal.speak(); // Output: Dog makes a noise.
-
Encapsulation
- Encapsulation involves hiding an object's internal representation from the outside.
class Car { constructor(brand) { this._brand = brand; } get brand() { return this._brand; } set brand(newBrand) { this._brand = newBrand; } } const myCar = new Car('Ford'); console.log(myCar.brand); // Output: Ford myCar.brand = 'BMW'; console.log(myCar.brand); // Output: BMW
-
Inheritance
- Inheritance allows a class to inherit properties and methods from another class.
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { speak() { console.log(`${this.name} barks.`); } } const d = new Dog('Mitzie'); d.speak(); // Output: Mitzie barks.
-
Polymorphism
- Polymorphism enables objects of different classes to be treated as instances of a common superclass.
class Animal { speak() { console.log('Animal speaks'); } } class Cat extends Animal { speak() { console.log('Meow'); } } class Dog extends Animal { speak() { console.log('Woof'); } } function makeAnimalSpeak(animal) { animal.speak(); } makeAnimalSpeak(new Cat()); // Output: Meow makeAnimalSpeak(new Dog()); // Output: Woof
-
Abstraction
- Abstraction involves creating simple models to represent complex real-world objects.
class Vehicle { startEngine() { console.log('Engine started'); } stopEngine() { console.log('Engine stopped'); } } class Car extends Vehicle { startEngine() { console.log('Car engine started'); } } const myCar = new Car(); myCar.startEngine(); // Output: Car engine started
-
Constructors and the new Keyword
- Constructors are special functions for creating and initializing objects.
class Person { constructor(name, age) { this.name = name; this.age = age; } } const person = new Person('Alice', 25); console.log(person); // Output: Person { name: 'Alice', age: 25 }
-
Methods — Instance, Static, and Prototype Methods
- Methods in JavaScript can be instance, static, or prototype methods.
class Rectangle { constructor(width, height) { this.width = width; this.height = height; } // Instance method getArea() { return this.width * this.height; } // Static method static compareArea(rect1, rect2) { return rect1.getArea() - rect2.getArea(); } } const rect1 = new Rectangle(5, 8); const rect2 = new Rectangle(6, 7); console.log(Rectangle.compareArea(rect1, rect2)); // Output: -2
-
Getters and Setters
- Getters and setters allow you to define Object Accessors (Computed Properties).
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } get fullName() { return `${this.firstName} ${this.lastName}`; } set fullName(name) { [this.firstName, this.lastName] = name.split(' '); } } const person = new Person('John', 'Doe'); console.log(person.fullName); // Output: John Doe person.fullName = 'Jane Smith'; console.log(person.fullName); // Output: Jane Smith
-
Inheritance with extends and super
- The
extends
keyword is used to create a child class from a parent class.
class Shape { constructor(name) { this.name = name; } move() { console.log(`${this.name} moved`); } } class Circle extends Shape { constructor(radius) { super('Circle'); this.radius = radius; } } const myCircle = new Circle(5); myCircle.move(); // Output: Circle moved
- The
Differences Between OOP and Functional Programming:
- State and Immutability: OOP manages state within objects, which can change over time. Functional programming prefers immutable data structures and pure functions without side effects.
- Methodology: OOP models real-world entities using objects and classes, while functional programming focuses on computation and avoids changing state.
- Code Reusability: In OOP, reusability comes through inheritance and polymorphism. Functional programming achieves reusability through functions and higher-order functions.
When to Use OOP or Functional Programming:
-
Use OOP when:
- You’re dealing with a complex system with clearly defined types and relationships.
- Your application’s state changes frequently and needs cohesive management.
- You prefer a modular, structured approach to organizing code.
-
Use Functional Programming when:
- You need a system with operations that don’t depend on or alter the state.
- Your focus is on data flow and transformations.
- You aim for code that’s easy to test and reason about, thanks to its immutability and purity.
Object-oriented programming in JavaScript offers a powerful way to structure and organize code, especially for complex applications. Although it differs from functional programming, both paradigms have unique strengths and can be combined within a single project. Understanding both OOP and functional programming makes you a more versatile and effective JavaScript developer.
Here's how you can approach each of these practice problems:
Q1: Create a Class to Create a Complex Number. Create a Constructor to Set the Real and Imaginary Parts.
class ComplexNumber {
constructor(real, imaginary) {
this.real = real;
this.imaginary = imaginary;
}
}
// Example usage:
let num1 = new ComplexNumber(3, 4); // Complex number: 3 + 4i
console.log(`Complex Number: ${num1.real} + ${num1.imaginary}i`);
class ComplexNumber {
constructor(real, imaginary) {
this.real = real;
this.imaginary = imaginary;
}
add(otherComplex) {
return new ComplexNumber(
this.real + otherComplex.real,
this.imaginary + otherComplex.imaginary
);
}
}
// Example usage:
let num1 = new ComplexNumber(3, 4);
let num2 = new ComplexNumber(1, 2);
let sum = num1.add(num2);
console.log(`Sum: ${sum.real} + ${sum.imaginary}i`);
class Human {
speak() {
console.log("Hello, I am a human.");
}
}
class Student extends Human {
speak() {
console.log("Hello, I am a student.");
}
}
// Example usage:
let person = new Human();
person.speak(); // Output: "Hello, I am a human."
let student = new Student();
student.speak(); // Output: "Hello, I am a student."
console.log(student instanceof Human); // Output: true
console.log(student instanceof Student); // Output: true
console.log(person instanceof Student); // Output: false
class ComplexNumber {
constructor(real, imaginary) {
this._real = real;
this._imaginary = imaginary;
}
get real() {
return this._real;
}
set real(value) {
this._real = value;
}
get imaginary() {
return this._imaginary;
}
set imaginary(value) {
this._imaginary = value;
}
}
// Example usage:
let num = new ComplexNumber(5, 6);
console.log(`Before: ${num.real} + ${num.imaginary}i`);
num.real = 7; // Using setter
num.imaginary = 8; // Using setter
console.log(`After: ${num.real} + ${num.imaginary}i`); // Using getter
- Q1: We defined a
ComplexNumber
class with a constructor to initialize the real and imaginary parts. - Q2: Added a method to sum two complex numbers.
- Q3: Demonstrated inheritance by creating a
Student
class fromHuman
and overriding a method. - Q4: Used the
instanceof
keyword to check if an object is an instance of a particular class. - Q5: Implemented getters and setters to access and modify the real and imaginary parts of the complex number.