Skip to main content

Session 8

Javascript Classes

JavaScript Classes, introduced in ES6, provide a clean, syntactic sugar over JavaScript's prototype-based inheritance, enabling true object-oriented programming (OOP) patterns. While JavaScript has always supported objects and prototypes, classes offer a familiar, template-driven approach to defining blueprints for objects with shared properties and methods. This session shifts focus from procedural scripting to OOP design, covering class declarations, constructors, instantiation, getters/setters, and inheritance.

Objectives

  • Understand OOP architecture in JavaScript
  • Define classes and instantiate objects with methods
  • Implement getters and setters for controlled property access
  • Apply inheritance using extends and super
  • Solve hands-on exercises modeling real-world entities (library books, products)

What is a JavaScript Class?

  • A class is a template/blueprint for creating objects.
  • It encapsulates data (properties) and behavior (methods).
  • Under the hood, classes still use JavaScript’s prototype chain, but the syntax is more readable and maintainable.

Class Declarations vs. Expressions

Type Syntax Hoisting/Scope
Declaration class MyClass {} Not hoisted. Must be defined before use. Global/module scope.
Expression const MyClass = class {} Runs immediately. Scope limited to assignment. Can be named or unnamed.

Constructor & Instantiation

  • The constructor() method runs automatically when a new object is created.
  • Used to initialize instance properties.
  • Objects are instantiated using the new keyword.
		class Bike {
  constructor(make, year) {
    this.make = make;
    this.year = year;
  }
  getAge() {
    return new Date().getFullYear() - this.year;
  }
}
const myBike = new Bike("Honda", 2021);
console.log(myBike.getAge()); // e.g., 5
	

Getters & Setters

  • Allow controlled access and validation for internal properties.
  • Syntax uses get and set keywords.

Important: Getter/setter names must not match the internal property name to avoid infinite recursion.

		class User {
  constructor(name) { this._name = name; }
  get name() { return this._name; }
  set name(val) { 
    if (val.length > 0) this._name = val.toUpperCase(); 
  }
}
	

Inheritance (extends & super)

  • Child classes inherit properties/methods from parent classes using extends.
  • super() must be called in the child constructor before accessing this.
  • Enables code reuse, method overriding, and polymorphism.
		class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} makes a sound.`; }
}
class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Calls parent constructor
    this.breed = breed;
  }
  speak() { return `${this.name} barks!`; } // Overrides parent method
}
	

Best Practices & Common Pitfalls

Pitfall Best Practice
Forgetting super() in derived constructor Always call super() first in child class constructors
Naming getters/setters identical to properties Use _property internally to prevent infinite recursion
Treating classes like functions Classes are not hoisted; define before use
Overusing deep inheritance chains Prefer composition when relationships aren't strict is-a

Quick Guide

		// 🔹 Basic Class
class Product {
  constructor(id, name) { this.id = id; this.name = name; }
  getInfo() { return `${this.id}: ${this.name}`; }
}
 
// 🔹 Getters & Setters
class User {
  constructor(age) { this._age = age; }
  get age() { return this._age; }
  set age(val) { if(val >= 0) this._age = val; }
}
 
// 🔹 Inheritance
class Student extends User {
  constructor(age, grade) { super(age); this.grade = grade; }
  status() { return `${this.age}yo, Grade ${this.grade}`; }
}
	

Question 1

Problem Statement

Let us assume you need to organize a library of some electronic manuals and novels for a particular company. For each book, you need to store following information:

  • The title
  • The author
  • The copyright date
  • The ISBN
  • The number of pages
  • The number of times the book has been checked out.
  • Whether the book has been discarded

Company wants to perform certain actions when the any book is outdated. The manual books must be exited after 5 years while a novel book should be exited if its checked out time crossed 100.

Task 1.Construct three classes that hold the information needed by company. One class should be a Book class and two child classes of the Book class called Manual and Novel. Each class will contain two methods. One will be a constructor. The other one will either be in charge of disposal of the book or updating the property related to the number of times a book has been checked out.

Task 2: Create an object of the Novel class and Manual class with some valid details.

Task 3: Write the method to count the duration of a manual book and checkout time for novel book so that they can be discarded based on the duration.

Requirements

  • Create Book base class + Manual & Novel child classes
  • Store: title, author, copyright date, ISBN, pages, checkout count, discarded status
  • Manual: discard if age > 5 years
  • Novel: discard if checkouts > 100
  • Each class: 1 constructor + 1 method (disposal or checkout update)
  • Create objects & implement duration/checkout tracking

Demo

📖 Library Book Management

Code

library.html
		<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Session 8 Ex1: Library System</title>
        <style>
            body {
                font-family: sans-serif;
                padding: 20px;
                max-width: 700px;
                margin: auto;
            }
            .card {
                background: #f9f9f9;
                padding: 15px;
                margin-bottom: 10px;
                border-radius: 5px;
                border-left: 4px solid #0056b3;
            }
        </style>
    </head>
    <body>
        <h2>📖 Library Book Management</h2>
        <div id="output"></div>
 
        <script>
            // Task 1: Base Class
            class Book {
                constructor(title, author, copyrightDate, ISBN, pages) {
                    this.title = title;
                    this.author = author;
                    this.copyrightDate = copyrightDate;
                    this.ISBN = ISBN;
                    this.pages = pages;
                    this.checkoutCount = 0;
                    this.discarded = false;
                }
            }
 
            // Manual Child Class (Discard after 5 years)
            class Manual extends Book {
                constructor(title, author, copyrightDate, ISBN, pages) {
                    super(title, author, copyrightDate, ISBN, pages);
                }
                checkAndDiscardByAge() {
                    const currentYear = new Date().getFullYear();
                    const age = currentYear - this.copyrightDate;
                    if (age > 5) this.discarded = true;
                    return { age, discarded: this.discarded };
                }
            }
 
            // Novel Child Class (Discard after 100 checkouts)
            class Novel extends Book {
                constructor(title, author, copyrightDate, ISBN, pages) {
                    super(title, author, copyrightDate, ISBN, pages);
                }
                updateCheckoutAndCheck() {
                    this.checkoutCount++;
                    if (this.checkoutCount > 100) this.discarded = true;
                    return {
                        count: this.checkoutCount,
                        discarded: this.discarded,
                    };
                }
            }
 
            // Task 2 & 3: Instantiate & Test
            const manual1 = new Manual(
                "C++ Programming",
                "Bjarne Stroustrup",
                2018,
                "978-0321563842",
                1300,
            );
            const novel1 = new Novel(
                "1984",
                "George Orwell",
                1949,
                "978-0451524935",
                328,
            );
 
            const mStatus = manual1.checkAndDiscardByAge();
            for (let i = 0; i < 101; i++) novel1.updateCheckoutAndCheck();
            const nStatus = {
                count: novel1.checkoutCount,
                discarded: novel1.discarded,
            };
 
            // Display Results
            document.getElementById("output").innerHTML = `
      <div class="card">
        <strong>📘 Manual:</strong> "${manual1.title}"<br>
        Age: ${mStatus.age} years | Checkouts: ${manual1.checkoutCount}<br>
        Status: <span style="color:${mStatus.discarded ? "red" : "green"}">${mStatus.discarded ? "❌ Discarded (Outdated)" : "✅ Active"}</span>
      </div>
      <div class="card">
        <strong>📗 Novel:</strong> "${novel1.title}"<br>
        Checkouts: ${nStatus.count} | Max Allowed: 100<br>
        Status: <span style="color:${nStatus.discarded ? "red" : "green"}">${nStatus.discarded ? "❌ Discarded (Overused)" : "✅ Active"}</span>
      </div>
    `;
        </script>
    </body>
</html>
	

HTML View

Question 2

Problem Statement

Create a product with properties: ID, Name, Description and Price. The create function for this object called displayProductDetails(). This function when invoked should display the name, description and discounted price of the product. For the calculation of discounted price you need to create another function CalculateDisc(percentage). The discount percentage would be given by user.

Requirements

  • Create product object with: ID, Name, Description, Price
  • Method displayProductDetails() → shows name, description, discounted price
  • Method CalculateDisc(percentage) → computes discounted price
  • Discount percentage provided by user

Demo

Product Discount Calculator

Code

product.html
		<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Session 8 Ex2: Product Discount</title>
        <style>
            body {
                font-family: sans-serif;
                padding: 20px;
                max-width: 500px;
                margin: auto;
            }
            input,
            button {
                padding: 10px;
                margin: 5px;
                width: 100%;
                box-sizing: border-box;
            }
            pre {
                background: #f4f4f4;
                padding: 15px;
                border-radius: 5px;
                white-space: pre-wrap;
            }
        </style>
    </head>
    <body>
        <h2>Product Discount Calculator</h2>
        <input
            id="discPercent"
            type="number"
            placeholder="Enter Discount % (e.g., 20)"
        />
        <button id="calcBtn">Calculate & Display Details</button>
        <pre id="output">Waiting for input...</pre>
 
        <script>
            // Lab Requirement: Object with properties & methods
            const product = {
                id: "P1001",
                name: "Wireless Mechanical Keyboard",
                description: "RGB backlit, USB-C charging, Blue switches",
                price: 149.99,
 
                CalculateDisc: function (percentage) {
                    return this.price - this.price * (percentage / 100);
                },
 
                displayProductDetails: function (percentage) {
                    const discPrice = this.CalculateDisc(percentage);
                    return `📦 Name: ${this.name}\n📝 Description: ${this.description}\n💰 Original Price: $${this.price}\n🏷️  Discounted Price: $${discPrice.toFixed(2)}`;
                },
            };
 
            document.getElementById("calcBtn").addEventListener("click", () => {
                const percent =
                    parseFloat(document.getElementById("discPercent").value) ||
                    0;
                document.getElementById("output").textContent =
                    product.displayProductDetails(percent);
            });
        </script>
    </body>
</html>
	

HTML View