All topics
Objectsadvanced

Composition Over Inheritance

Building complex objects by combining small, focused behaviors together rather than through deep class inheritance hierarchies.

Composition over inheritance is a design principle favoring building up complex object behavior by combining smaller, independent pieces (functions, mixins, or plain objects) rather than by creating deep class hierarchies where subclasses inherit and override behavior from parent classes. It's a design-level topic rather than a syntax quiz, and senior-level interviews often bring it up to gauge architectural judgment rather than just language trivia.

Inheritance is like building furniture by only ever taking one existing chair and modifying it into slightly different chairs each generation — eventually you're stuck if you need something that's part-chair, part-ladder. Composition is like building with modular LEGO pieces: you snap together exactly the capabilities you need for this specific object, without being constrained by what any single 'parent brick' looked like.

Key Concepts

1
Deep inheritance hierarchies tend to become fragile as they grow: a change to a base class can ripple unpredictably through every subclass (the 'fragile base class' problem), and modeling behaviors that don't fit neatly into a single-parent hierarchy — like a FlyingCar that needs both Vehicle and Flyable behavior — is awkward with single inheritance, since a class can only extend one direct parent in JavaScript. Multiple inheritance-like behavior has to be faked through mixins or interfaces in languages that support them.
FlyingCarVehicleFlyableextend
2
Composition sidesteps this by building objects out of independent, focused pieces of behavior and combining them as needed, rather than being locked into one ancestor. In JavaScript this often takes the form of factory functions that return objects built from a combination of smaller behavior-providing functions, or 'mixins' — functions that take a class/object and return an augmented version of it with additional methods copied on, letting you combine multiple mixins on the same base object without needing them to share a common ancestor.
3
The common advice — 'favor composition over inheritance' — doesn't mean inheritance is always wrong; a shallow, well-understood inheritance hierarchy (like the built-in Error subclasses, or a handful of UI component base classes) is often perfectly fine. The judgment call is about avoiding deep, rigid hierarchies for behavior that's more naturally described as a combination of independent capabilities, which composition expresses far more flexibly since pieces can be mixed, matched, and swapped independently without restructuring an entire class tree.
Error