JavaScript Mixins for Functional Inheritance

Mixins are a way to add the functionality of 1 or more objects to a new object, essentially creating a non-standard means of inheritance. This inheritance is also done functionally, which is the way JavaScript seems to like having things done. Basically all we're doing is reusing functions without the need for the standard inheritance model.

Mixin Structure

What is a Mixin?

Let's say we're creating controls to put on a web page. These controls can be either links or they can be buttons. They can either just go to a URL or take a callback for a click event. Buttons can even be different shapes. So how would we create a rectangular button the does something special on a click? We can't just inherit the methods associated with buttons, click controls, and rectangles using the standard prototypal inheritance; we can only inherit from one of them.

Mixins allow you to define a set of functionality for a type (button, rectangle, etc) and then you can add that functionality to any object by extending it. I'll show you an example of a possible rectangle mixin.

var rectangle = {
    setWidth: function(w) {
        this.width = w;
    },
    setHeight: function(h) {
        this.height = h;
    },
    draw: function() {
        // draw a rectangle based on the 
        // height/width specified.
    }
}

This isn't very useful by itself, but now anything that wants to have a rectangular shape can reuse these functions very easily. Below you'll see the RectangleClickButton using this along with a couple other mixins (that I won't bother implementing).

var RectangleClickButton = function(w, h, text, callback) {
    this.setWidth(w);        // from rectangle mixin
    this.setHeight(h);        // from rectangle mixin
    this.setText(text);        // from button mixin
    this.onclick(callback);    // from onclickControl mixin
};

extend(RectangleClickButton.prototype, rectangle);
extend(RectangleClickButton.prototype, button);
extend(RectangleClickButton.prototype, onclickControl);

You may be looking at that and thinking, "what the heck is that extend function?" That's what I'm showing you next. It simply copies all the properties from one object to another. Check it out:

function extend(destination, source) {
    for (var prop in source) {
        if (source.hasOwnProperty(prop)) {
            destination[prop] = source[prop];
        }
    }
}

An Alternative Mixin Technique

The above extend function poses a small problem, though, because it is global, and I think that the word "extend" is common enough that we should pull it out of the global namespace. You might jump right to the conclusion of creating an object named Mixin – or something similar – and adding the extend function to it, but I have another idea that is easier (and shorter) to use. We'll extend the native Object object to have a function that does the extension work.

Object.prototype.addMixin = function (mixin) {    
    for (var prop in mixin) {
        if (mixin.hasOwnProperty(prop)) {
            this.prototype[prop] = mixin[prop];
        }
    }
};

With that in place you can now add mixins like this:

RectangleClickButton.addMixin(rectangle);
RectangleClickButton.addMixin(button);
RectangleClickButton.addMixin(onclickControl);

Mixin it All Up

That's all there is to it. I can see quite a few scenarios where this could come in handy and it's a bit simpler to understand than traditional prototypal inheritance. There is even another mixin technique described here that the author calls "Functional Mixins." It's worth taking a look, but I prefer the second technique that I showed above. Do you have any interesting uses for the mixin? If you do, or if you just want to give some feedback, leave a comment below. You could also share this technique with your friends via the sharing buttons below. Happy Coding!

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.