Let’s first see what differentiates a mixin from a derived class. When you derive one class from another, the new class is the combination of the base class’ members and those additional ones you specify for the derivation. In WinJS.Class.derive, you can only specify one base class.
In object-oriented programming, there is the concept of multiple inheritance whereby you can derive a class from multiple base classes. This is frequently used to attach multiple independent interfaces on the new class (it’s used all the time in Win32/COM programming, where an interface is typically defined as a virtual base class with no implementation, and provides the necessary function signatures to the derived class).
Hence the idea of a mix or mixin, which isn’t unique to WinJS as evidenced by this article on Wikipedia. WinJS.Class.mix is basically a way to do something like multiple inheritance by simply mixing together all the instance members of any number of other mixin objects. The description in the documentation for WinJS.Class.mix puts it this way: “Defines a class using the given constructor and the union of the set of instance members specified by all the mixin objects. The mixin parameter list is of variable length.”
So here we see two other differences between a mix and a derivation: a mix does not operate on static members, and does not concern itself with any constructors other than the one given directly to WinJS.Class.mix. (This is also why it’s not true multiple inheritance in the strict object-oriented sense.)
WinJS itself uses the mixing concept for its own implementation. If you look in the docs, you’ll see that there are several mixins in WinJS that you can use yourself: WinJS.UI.DOMEventMixin, WinJS.Utilities.eventMixin, WinJS.Binding.observableMixin, and WinJS.Binding.dynamicObservableMixin:
- WinJS.UI.DOMEventMixin contains standard implementations of addEventListener, removeEventListener, dispatchEvent, and setOptions, which are commonly used for custom controls. If you look in the WinJS file ui.js, you’ll see that all the WinJS controls bring this into their mix.
- WinJS.Utilities.eventMixin is basically the same thing without setOptions, as it is meant for objects that don’t have associated UI elements (it also can’t just use the listener methods on the element in the DOM, so it has its own implementation of these methods).
- WinJS.Binding.observableMixin adds functionality to an object that makes it “observable” meaning that it can participate in data binding. This consistes of methods bind, unbind, and notify. This is used with the WinJS.Binding.List class.
- WinJS.Binding.dynamicObservableMixin builds on the idea with methods called setProperty, getProperty, updateProperty, addProperty, and removeProperty. This is helpful for wiring up two-way data binding, something that WinJS doesn’t do itself, but isn’t too hard to pull together. The Declarative binding sample in the SDK shows how.
With events (in the first two mixins), you commonly use WinJS.Utilities.createEventProperties to also create all the stuff a class needs to support named events. createEventProperties returns a mixin object that you can then use with WinJS.Class.mix. For example, if you pass this method an array with just [“statusChanged”] when you’ll get a function property in the mixin names onstatuschanged and the ability to create a listener for that event.
So mixins, again, are a way to add pre-canned functionality to a class, and is a convenient way to modularive code that you’ll use in multiple classes. It’s also good to know that you can call WinJS.Class.mix multiple times with additional mixins, and the results simply accumulate (if there are duplicates, the last member mixed is the one retained).