Skip to content

Classes

Classes provide a cleaner, more intuitive syntax for creating objects and implementing inheritance in JavaScript. Introduced in ES6 (2015), they’re syntactic sugar over JavaScript’s prototype-based inheritance.

Before ES6, you created object “classes” using constructor functions and prototypes:

// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
// Adding methods via prototype
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
// Inheritance
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
const alice = new Student("Alice", 20, "A");

ES6 classes provide cleaner syntax:

class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
// Static method
static species() {
return "Homo sapiens";
}
}
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
study() {
return `${this.name} is studying`;
}
}
const alice = new Student("Alice", 20, "A");
console.log(alice.greet()); // "Hello, I'm Alice"
console.log(alice.study()); // "Alice is studying"
  • Clearer syntax: Less boilerplate, more readable
  • Natural inheritance: extends and super keywords
  • Static methods: Easy to define class-level methods
  • Familiar: Syntax similar to other OOP languages (Java, C#, Python)
  • Hoisting: Classes aren’t hoisted, preventing subtle bugs
  • Classes are not hoisted (unlike function declarations)
  • Class methods are non-enumerable by default
  • Must call super() before using this in subclass constructor
  • Classes are strict mode by default
  • Class declarations don’t support semicolons between methods
  • Private fields use # prefix (ES2022): #privateField
class BankAccount {
#balance = 0; // private field
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
  1. Create a Car class with properties brand and model, and a method describe() that returns "This is a [brand] [model]".

    Answer
    class Car {
    constructor(brand, model) {
    this.brand = brand;
    this.model = model;
    }
    describe() {
    return `This is a ${this.brand} ${this.model}`;
    }
    }
  2. Create an ElectricCar class that extends Car and adds a batteryCapacity property.

    Answer
    class ElectricCar extends Car {
    constructor(brand, model, batteryCapacity) {
    super(brand, model);
    this.batteryCapacity = batteryCapacity;
    }
    }
  3. What happens if you forget to call super() in a subclass constructor?

    Answer ReferenceError: Must call super constructor before accessing 'this' in derived class