Javascript | Composition vs Inheritance
Many developers begin their journey with an Object-Oriented Programming (OOP) language such as Ruby or Python. These new developers soon find out that a core concept in OOP is classes. When shifting over to Javascript, a Functional Programming (FP) language, the natural instinct is to use the same programming paradigm that was used in OOP. Javascript, and its prototype chain, make an inheritance-based architecture possible.
I will be doing a deep dive into an alternative to inheritance called composition. This approach makes use of the fact that in Javascript, functions are first-class objects. Composition is a highly flexible and modular architecture that many experts believe should in almost all instances be chosen over inheritance.

Inheritance | A Logical First Step
Inheritance, as the name suggests, is a programming paradigm that heavily borrows from its namesake in Biology. In the same way species have a well-defined relationship so do classes in OOP.
In Biology you could construct an evolutionary tree where you have animals
at the top of the chain. From animals
you could branch to mammals
which branches to humans
which branches to you
(I’m assuming you’re a human and not a Labrador with a penchant for Javascript).
Some properties belong to each of those items in the chain. We could say that all animals
breathe air . There are, however, some properties not shared by all. For example, not all animals
can play the trombone. Not all mammals
can play the trombone either. It is only once we hit the branch for humans
that the trombone-playing characteristic becomes relevant.
You may have noticed the pattern that inheritance is top down. Animals
have the characteristic of breathing air and therefore all items in the chain below it also breathe air. Humans
can play the trombone and therefore everything below it also has the potential to play the trombone (yes you
— time to start those lessons). This is exactly how prototypal inheritance works in Javascript. As you’ll see in the code below the property for breathes
is available to all objects yet trombone
is only available to human and you.
Inheritance is fantastic because it uses a methodology for defining relationships that we are already familiar with. Conceptually it is easily understandable and relationships are highly structured and predictable.
Some Downsides to Inheritance
Everything in the code above is peachy until one day you turn on your TV to see a news report about a dolphin
that can play the trombone. Your first instinct is probably to think what a crazy, amazing world we live in. Then you realize that this has completely ruined your inheritance structure. We now have a second mammal
that can also play the trombone.

Let’s start off by thinking where the dolphin
lives in the prototype chain. If we inserted it below human
it would then have access to the trombone
property. That problem would be solved but others would be created as now the dolphin
would also have access to the rest of the human’s
unique properties such as their ability to read, write & construct buildings. A possible way to fix this is to add a new object to the prototype chain below mammals, e.g. mammals that play music. We could move the trombone-playing property to this object rather than defining it in human
. Dolphin
and human
can now both inherit the trombone
property from this object.

It looks really messy but at least our problem is solved. That is until we discover an alligator than can play the trombone. An alligator is a reptile, not a mammal, solving this problem is starting to become an enormous mess!

Now we can start to see the problem with inheritance. All is well and good when the objects and their properties are orderly and predictable. In life we cannot predict the future. Models can evolve such that their relationships can completely change over time. We need an approach where changing a model’s properties is more flexible. This brings us to the concept of composition.
Composition | A Flexible Solution
Another downside of inheritance, that we haven’t discussed yet, is the excess baggage it tends to weigh down on objects. Objects don’t only inherit their immediate parent’s properties— they inherit all of the properties from all of the objects in the prototype chain above them. The animal
, mammal
and human
objects may each have hundreds of properties associated with them. When we define you
we probably only really need a handful of them. Having all of those excess, unused properties is unnecessary bloat which slows your code down. Wouldn’t it be great if we could define objects such that we could hand-pick the properties that best describe them? That is exactly what composition offers.
Composition combines the power of first-class functions and factory functions. First-class functions means that Javascript can pass functions in as arguments to other functions. It also means that functions can be returned as results from other functions. Factory functions are simply functions that return an object. We can re-define the inheritance-based approach above such that the properties for breathes
and trombone
are stand-alone functions. We can then bind the relevant characteristics on to each individual object definition. I’ve added properties for land/sea bound to make the concept clearer.
If we somewhere down the line discover an Amoeba that can play the trombone, construct buildings and is well-versed in Russian literature, creating this object using composition will be no problem at all. This is the magic of using composition rather than inheritance.