JavaScript Classes
Classes in JavaScript provide a cleaner way to create objects and handle inheritance. They’re built on prototypes but use familiar object-oriented syntax. Classes make your code more organized and reusable.
What Are Classes?
Classes are blueprints for creating objects. They define properties and methods that objects created from the class will have.
Before classes, we used constructor functions:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`Hello, I'm ${this.name}`);
};With classes, it’s more readable:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}Creating Objects
Use the new keyword to create instances:
let person1 = new Person('Alice', 30);
let person2 = new Person('Bob', 25);
person1.greet(); // "Hello, I'm Alice"
person2.greet(); // "Hello, I'm Bob"
Class Methods
Methods are functions defined in the class:
class Calculator {
add(a, b) {
return a + b;
}
multiply(a, b) {
return a * b;
}
power(base, exponent) {
return Math.pow(base, exponent);
}
}
let calc = new Calculator();
console.log(calc.add(5, 3)); // 8
console.log(calc.power(2, 3)); // 8
Constructor
The constructor method runs when you create a new instance. It’s where you set up initial properties:
class Car {
constructor(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
this.mileage = 0;
}
drive(miles) {
this.mileage += miles;
console.log(`Drove ${miles} miles. Total: ${this.mileage}`);
}
}
let myCar = new Car('Toyota', 'Camry', 2020);
myCar.drive(50); // "Drove 50 miles. Total: 50"
Getters and Setters
Use getters and setters for computed properties:
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
set area(value) {
// Assume square for simplicity
let side = Math.sqrt(value);
this.width = side;
this.height = side;
}
}
let rect = new Rectangle(10, 20);
console.log(rect.area); // 200
rect.area = 144; // Sets width and height to 12
console.log(rect.width, rect.height); // 12, 12
Static Methods
Static methods belong to the class, not instances:
class MathUtils {
static add(a, b) {
return a + b;
}
static randomBetween(min, max) {
return Math.random() * (max - min) + min;
}
}
// Call without creating instance
console.log(MathUtils.add(5, 3)); // 8
console.log(MathUtils.randomBetween(1, 10)); // Random number
Inheritance
Classes can extend other classes:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}
speak() {
console.log(`${this.name} barks`); // Override method
}
fetch() {
console.log(`${this.name} fetches the ball`);
}
}
let dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // "Buddy barks"
dog.fetch(); // "Buddy fetches the ball"
super() calls the parent constructor. You can override methods by defining them again.
Private Fields
Use # for private properties (ES2022+):
class BankAccount {
#balance = 0; // Private field
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
let account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
// console.log(account.#balance); // Error: private field
When to Use Classes
Classes are great for:
- Creating multiple similar objects
- Organizing related data and behavior
- Implementing inheritance
- Building complex applications
For simple objects, plain objects or factory functions might be better.
Classes are syntactic sugar over prototypes. To understand the underlying mechanism, see JavaScript prototypes.
The MDN Classes guide has comprehensive examples.