By the end of this lesson, you will be able to write JavaScript classes with constructors, methods, inheritance, and static members, and explain how classes provide a clearer syntax over prototypes.
What it is
A JavaScript class is a blueprint for creating objects that share behavior. It is not a new object model; it is syntactic sugar over the existing prototype-based system. When you write class Dog, JavaScript still creates a constructor function and puts methods on its prototype. Related terms include constructor, prototype, instance, extends, super, static, and private fields.
Why it matters
- It groups related data and behavior in one readable unit.
- It makes inheritance explicit with
extendsandsuper. - It supports encapsulation through private fields like
#balance. - It helps organize larger applications, such as UI components, services, and domain models.
- It gives familiar object-oriented syntax while keeping JavaScript's prototype power.
Syntax or steps
The smallest useful class has a name, a constructor, and optional methods.
class ClassName {
constructor(parameter) {
this.property = parameter;
}
methodName() {
return this.property;
}
}
Use new ClassName() to create an instance. Use extends to inherit from another class, and call super() inside the child constructor before using this.
Example
class Dog {
constructor(name, breed) {
this.name = name;
this.breed = breed;
}
speak() {
return `${this.name} says woof.`;
}
}
class GuideDog extends Dog {
constructor(name, breed, owner) {
super(name, breed);
this.owner = owner;
}
speak() {
return `${super.speak()} I guide ${this.owner}.`;
}
}
const buddy = new GuideDog("Buddy", "Labrador", "Maya");
console.log(buddy.speak());
Part by part:
class Dogdefines the parent blueprint.constructorstoresnameandbreedon each new object.speak()is a prototype method shared by all dogs.class GuideDog extends Dogcreates a child class.super(name, breed)calls the parent constructor to set inherited properties.super.speak()calls the parent method before adding child behavior.new GuideDog(...)creates an instance with both parent and child properties.
Common mistakes
- Forgetting
new. CallingDog()withoutnewthrows a class constructor error. Fix: usenew Dog(). - Using
thisbeforesuper()in a child constructor. Fix: callsuper()first. - Assuming methods are copied to each instance. Fix: remember methods live on the prototype and are shared.
- Overusing inheritance for simple data objects. Fix: prefer plain objects or factory functions when behavior is minimal.
When to use it
Compare classes with factory functions.
| Approach | Best for | Trade-off |
|---|---|---|
| Class | Shared behavior, inheritance, private state, larger object models | Can feel heavier for simple data |
| Factory function | Creating simple objects without inheritance | Less built-in syntax for private fields and inheritance |
Use a class when you need a clear blueprint with methods and inheritance. Use a factory function when you only need to return an object with properties.
Practice
Guided exercise: create a BankAccount class with a private #balance field, a deposit(amount) method, and a getBalance() method.
class BankAccount {
#balance = 0;
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
Challenge: add a withdraw(amount) method that returns "Insufficient funds" if the amount is greater than the balance.
Expected output hint: after depositing 100 and withdrawing 30, getBalance() should return 70.
Quick check
Question: Where do class methods live in JavaScript?
Answer: They live on the class prototype and are shared by instances, not copied into each object.
Summary
JavaScript classes give you a readable way to define constructors, methods, inheritance, and private state. They still use prototypes underneath, so understanding prototype, new, and super makes them easier to use correctly.