When it comes to advanced class composition, JavaScript has quite a number of approaches - a true smorgasbord of options. A type of pattern that is rarely spotted in the wild is the mixin-based inheritance pattern. Mixins are usually skipped by new JavaScript programmers (I did it too). I don’t want to complain but mixins can sometimes be quite dense to write and comprehend. But they come with a bunch of features that are worth looking into.
The mixin pattern - as the name suggests - is a pattern of mixing together an object with other objects to add properties we need. Think of it like add-ons that can give your object additional properties, but these individual properties are not really subclasses themselves.
On the surface, mixins behave like object mixing layers, where we pass-in the target (the mixin) and the source. The target is appended to the source and a new object is returned.
A more accurate description is that a mixin works as factory where new a subclass object is returned. Through this whole process there is no definition of the subclass anywhere.
A more C++ analogy would be to compare them to abstract classes with virtual functions, allowing them to be inherited by other subclasses.
So, now that we know mixins allow us to create a modified definition that can be applied to existing superclasses to create new subclasses, let’s see how mixin would look like:
//The swim property here is the mixin
let swim = {
location() {
console.log(`Heading ${this.direction} at ${this.speed}`);
}
};
let Alligator = function(speed, direction) {
this.speed = speed,
this.direction = direction
};
//This is our source object
let alligator = new Alligator('20 mph','North');
alligator = Object.assign(alligator, swim);
console.log(alligator.location());
In the above snippet, we want to create an alligator that can swim. So we create a new alligator
and then give it the swim
feature. The swim
object is the mixin or an extension that we want the alligator
object to have using the Object.assign
method.
The Object.assign
method allows us to add more than one mixin at a time. A multiple mixin case would look like this:
alligator = Object.assign(alligator, swim, crawl);
Now let’s look how mixins can be used with ES6 classes:
let swim = {
setSwimProperties(speed, direction) {
this.speed = speed;
this.direction = direction;
},
getSwimProperties(){
console.log(`swimming ${this.speed} towards ${this.direction}`);
}
}
class Reptile {
constructor(name) {
this.name = name;
}
}
Object.assign(Reptile.prototype, swim);
let alligator = new Reptile("alligator");
alligator.setSwimProperties("5 m/s", "upstream");
alligator.getSwimProperties();
The advantage of adding functionality via the mixin approach is flexibility. The mixin being a very primitive function, as in it does exactly one thing, allows us to use these structures repeatedly and in a variety of scenarios. It can used with a native function call, used in a class definition, etc.
Another good thing is that it tends to keep the class hierarchy horizontal - by allowing superclasses to use the mixins to create new objects of desired subclass properties rather than making the inheritance chain longer for creating new sublasses for these cases.
Some things to keep in mind when using mixins though:
Object.assign
(both in object and class implementation) does only a shallow copy of the mixin properties.instanceof
operator cannot help us here.Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.