Class
A class is a blueprint for creating objects that share the same properties and methods. It defines the structure and behavior of a type of object; instances are individual objects created from that blueprint.
Explanation
In JavaScript, classes are syntactic sugar over the prototype-based inheritance that's always been JavaScript's object system. The class keyword (introduced in ES6) provides cleaner syntax but the underlying mechanism is the same: methods defined in the class body are added to the prototype; properties set in the constructor are set on each instance. A class has: a constructor (runs when you create an instance with new — initializes instance properties), instance methods (defined in the body, shared via prototype), static methods (called on the class itself, not instances — useful for factory methods and utilities), and getters/setters (computed property accessors). Private fields (#fieldName) are supported in modern JavaScript and are truly inaccessible outside the class — unlike the convention of prefixing with underscore, which was only a gentleman's agreement. Classes support single inheritance via extends. The child class must call super() in its constructor before accessing this. Method overriding: defining a method in the child class with the same name as the parent replaces it for instances of the child class. super.methodName() calls the parent's version. When to use classes: modeling entities with shared behavior and state (User, Product, EventEmitter), maintaining object-oriented design patterns, integrating with frameworks that expect class components (some legacy React code, Angular). When not to use classes: simple data containers (use plain objects), functions that don't need shared state (use standalone functions), or when functional patterns (closures, composition) are cleaner.
Code Example
javascript// JavaScript class fundamentals
class Animal {
#name; // private field
#sound;
constructor(name, sound) {
this.#name = name;
this.#sound = sound;
}
speak() {
return `${this.#name} says ${this.#sound}`;
}
get name() { return this.#name; } // getter
static create(name, sound) { // factory static method
return new Animal(name, sound);
}
}
// Inheritance
class Dog extends Animal {
#tricks = [];
constructor(name) {
super(name, 'woof'); // must call super() first
}
learn(trick) {
this.#tricks.push(trick);
return this; // enable method chaining
}
perform() {
return this.#tricks.map(t => `${this.name} performs ${t}`);
}
}
const rex = new Dog('Rex');
rex.learn('sit').learn('shake');
console.log(rex.speak()); // "Rex says woof"
console.log(rex.perform()); // ["Rex performs sit", ...]
// instanceof: check type hierarchy
console.log(rex instanceof Dog); // true
console.log(rex instanceof Animal); // true
Why It Matters for Engineers
Understanding classes explains how JavaScript's prototype chain works — the mechanism behind every method call, every instanceof check, and every extends. When debugging inheritance bugs (methods undefined on child instances, wrong this in event handlers) or reviewing AI-generated OOP code, you need to know what the class syntax compiles down to. Classes vs functions is also an ongoing architectural debate in JavaScript: React moved from class components to functional components + hooks because functions compose more easily and avoid this binding confusion. Understanding both patterns lets you make informed choices and work confidently in codebases using either style.
Related Terms
Learn This In Practice
Go deeper with the full module on Beyond Vibe Code.
Programming Foundations → →