JavaScript Classes and Inheritance
A class is a blueprint for creating many objects that have the same properties and methods.
Why Classes?
Suppose a shop in Saddar sells hundreds of products. Each product has a name, a price and a way to calculate a discount. Writing each object by hand would be slow and full of mistakes. A class lets you describe a product once and then create as many as you need with new.
Defining a Class
Example
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
priceAfter(percent) {
return this.price - this.price * percent / 100;
}
label() {
return `${this.name}: Rs ${this.price}`;
}
}
const fan = new Product("Ceiling Fan", 9500);
const iron = new Product("Steam Iron", 4200);
document.getElementById("demo").innerHTML =
fan.label() + "<br>" +
iron.label() + "<br>" +
"Fan with 10% off: Rs " + fan.priceAfter(10);
</script>
</body>
</html>Try it Yourself »Ceiling Fan: Rs 9500 Steam Iron: Rs 4200 Fan with 10% off: Rs 8550
| Part | What it does |
|---|---|
class Product { } | Declares the class. Class names start with a capital letter |
constructor(...) | Runs automatically when you write new Product(...) |
this.name = name | Saves a value on the new object |
label() { } | A method, shared by every product |
Each object made from a class is called an instance. fan instanceof Product is true.
Getters and Setters
A getter looks like a property but runs a function. A setter runs when you assign a value, so you can check it first.
Example
class Student {
constructor(first, last) {
this.first = first;
this.last = last;
this._marks = 0;
}
get fullName() {
return this.first + " " + this.last;
}
set marks(value) {
if (value < 0 || value > 100) {
throw new Error("Marks must be between 0 and 100");
}
this._marks = value;
}
get marks() {
return this._marks;
}
}
const s = new Student("Ayesha", "Khan");
s.marks = 88;
console.log(s.fullName, s.marks); // no brackets: they act like propertiesAyesha Khan 88
Private Fields
A name starting with # is private. It can only be used inside the class, so outside code cannot change it by mistake.
Example
class Wallet {
#balance = 0; // private field
deposit(amount) {
if (amount > 0) this.#balance += amount;
}
get balance() {
return this.#balance;
}
}
const w = new Wallet();
w.deposit(1500);
console.log(w.balance); // 1500
// w.#balance = 999999; SyntaxError: private fieldStatic Members
static methods and properties belong to the class itself, not to each instance. They are good for helpers and counters.
Example
class Ticket {
static count = 0;
constructor(passenger) {
Ticket.count++;
this.number = "PK-" + Ticket.count;
this.passenger = passenger;
}
static isValid(number) {
return number.startsWith("PK-");
}
}
const t1 = new Ticket("Hamza");
const t2 = new Ticket("Mehwish");
console.log(t2.number, Ticket.count, Ticket.isValid("PK-7"));PK-2 2 true
Inheritance With extends
extends creates a child class that gets everything from a parent class, and can add or change things. In the child's constructor, call super(...) first to run the parent's constructor.
Example
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
class Employee {
constructor(name, salary) {
this.name = name;
this.salary = salary;
}
describe() {
return `${this.name} earns Rs ${this.salary}`;
}
}
class Manager extends Employee {
constructor(name, salary, team) {
super(name, salary); // run Employee's constructor
this.team = team;
}
describe() {
// reuse the parent's version, then add to it
return super.describe() + ` and leads ${this.team.length} people`;
}
}
const staff = [
new Employee("Usman", 60000),
new Manager("Fatima", 150000, ["Usman", "Zara", "Imran"])
];
document.getElementById("demo").innerHTML = staff.map(p => p.describe()).join("<br>");
</script>
</body>
</html>Try it Yourself »Usman earns Rs 60000 Fatima earns Rs 150000 and leads 3 people
super(...)calls the parent constructor. You must call it before usingthis.super.method()calls the parent's version of a method.- Writing a method with the same name in the child overrides the parent's one.
Under the hood, classes use JavaScript's older prototype system. Methods live on Product.prototype and are shared by all instances. A class is simply a cleaner way to write it.
Exercise
Exercise
In a child class constructor, what must you call before using this?
