11. Classes
Class Declaration
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
get isAdult() {
return this.age >= 18;
}
set age(value) {
if (value < 0) {
throw new Error("Age cannot be negative");
}
this._age = value;
}
get age() {
return this._age;
}
}
const john = new Person("John", 30);
console.log(john.greet()); // "Hello, I'm John"
console.log(john.isAdult); // true
Class Expression
const Animal = class {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
};
const dog = new Animal("Dog");
console.log(dog.speak()); // "Dog makes a sound"
Inheritance
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
eat() {
return `${this.name} is eating`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}
speak() {
return `${this.name} barks`; // Override parent method
}
fetch() {
return `${this.name} is fetching`;
}
}
const dog = new Dog("Buddy", "Golden Retriever");
console.log(dog.speak()); // "Buddy barks"
console.log(dog.eat()); // "Buddy is eating" (inherited)
console.log(dog.fetch()); // "Buddy is fetching"
Static Methods and Properties
class MathUtils {
static PI = 3.14159;
static add(a, b) {
return a + b;
}
static multiply(a, b) {
return a * b;
}
}
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.add(5, 3)); // 8
console.log(MathUtils.multiply(4, 2)); // 8
// Static methods are not available on instances
const utils = new MathUtils();
// utils.add(1, 2); // Error
Private Fields and Methods (ES13+)
class BankAccount {
#balance = 0; // Private field
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
#calculateInterest() { // Private method
return this.#balance * 0.05;
}
getInterest() {
return this.#calculateInterest();
}
}
const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
console.log(account.getInterest()); // 75
// console.log(account.#balance); // Error: Private field
// account.#calculateInterest(); // Error: Private method
Getters and Setters
class Temperature {
constructor(celsius) {
this.celsius = celsius;
}
get fahrenheit() {
return this.celsius * 9/5 + 32;
}
set fahrenheit(value) {
this.celsius = (value - 32) * 5/9;
}
get kelvin() {
return this.celsius + 273.15;
}
set kelvin(value) {
this.celsius = value - 273.15;
}
}
const temp = new Temperature(25);
console.log(temp.fahrenheit); // 77
console.log(temp.kelvin); // 298.15
temp.fahrenheit = 86;
console.log(temp.celsius); // 30
Mixins
const Flyable = {
fly() {
return `${this.name} is flying`;
}
};
const Swimmable = {
swim() {
return `${this.name} is swimming`;
}
};
class Duck {
constructor(name) {
this.name = name;
}
}
Object.assign(Duck.prototype, Flyable, Swimmable);
const duck = new Duck("Donald");
console.log(duck.fly()); // "Donald is flying"
console.log(duck.swim()); // "Donald is swimming"
Abstract Classes (Convention)
class Shape {
constructor() {
if (this.constructor === Shape) {
throw new Error("Abstract class cannot be instantiated");
}
}
area() {
throw new Error("Method 'area()' must be implemented");
}
perimeter() {
throw new Error("Method 'perimeter()' must be implemented");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
perimeter() {
return 2 * Math.PI * this.radius;
}
}
const circle = new Circle(5);
console.log(circle.area()); // 78.53981633974483
console.log(circle.perimeter()); // 31.41592653589793
// const shape = new Shape(); // Error: Abstract class cannot be instantiated
Class Checking
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog.constructor === Dog); // true
console.log(Dog.prototype.isPrototypeOf(dog)); // true
Next Steps
Classes provide a cleaner syntax for object-oriented programming. Next, let's explore arrays and collections, which are essential data structures in ECMAScript.