Mixins should be seen as a handy form of code reuse.
Code that describes certain behavior of an object and also
tends to be copied over and over again, might be considered
of being collected/stored once into a mixin.
With the function based mixin/trait pattern in JavaScript
one also can make use of its stateful variant that offers
even more possibilities of how one might going to arrange
ones type/object architecture(s).
As already has been pointed, the OP's example is not that well
chosen in terms of fitting to mixin/trait based composition.
The next given code block nevertheless does try with a slightly
changed variant in order to demonstrate the different approaches
of applying function based mixin/trait patterns in JavaScript ...
function withObjectBaseIntrospection(state) { // - mixin that preserves injected
var // local state by creating a
object = this; // closure at call/apply time.
object.valueOf = function () {
return Object.assign({}, state);
};
object.toString = function () {
return JSON.stringify(state);
};
}
function withHardwareStandardGetters(state) { // - mixin that preserves injected
var // local state by creating a
hardware = this; // closure at call/apply time.
Object.defineProperty(hardware, "manufacturer", {
get: function () { return state.manufacturer; }
});
Object.defineProperty(hardware, "processorSpeed", {
get: function () { return state.processorSpeed; }
});
Object.defineProperty(hardware, "ram", {
get: function () { return state.ram; }
});
Object.defineProperty(hardware, "hardDiskSpace", {
get: function () { return state.hardDiskSpace; }
});
}
function withDesktopSpecificGetters(state) { // - mixin that preserves injected
var // local state by creating a
hardware = this; // closure at call/apply time.
Object.defineProperty(hardware, "bodyLength", {
get: function () { return state.bodyLength; }
});
Object.defineProperty(hardware, "bodyWidth", {
get: function () { return state.bodyWidth; }
});
Object.defineProperty(hardware, "bodyHeight", {
get: function () { return state.bodyHeight; }
});
}
function withHardwareSpecificQuality() { // - generic function based mixin pattern.
this.getQuality = function() {
return (this.processorSpeed * this.ram * this.hardDiskSpace);
};
this.isFast = function () {
return (this.processorSpeed > (this.ram / 4));
};
this.isRoomy = function () {
return (this.hardDiskSpace > Math.floor(this.ram * this.processorSpeed));
};
}
function withDesktopSpecificMeasures() { // - generic function based mixin pattern.
this.getBodyVolume = function() {
return (this.bodyLength * this.bodyWidth * this.bodyHeight);
};
}
class Computer {
constructor(state) {
withObjectBaseIntrospection.call(this, state); // - applying 2 "stateful mixin"
withHardwareStandardGetters.call(this, state); // at instance/object level.
}
}
withHardwareSpecificQuality.call(Computer.prototype); // - making use of inheritance via the
// constructor's prototype, but enriching the
// latter by a more generic mixin (at "class level").
class Desktop extends Computer { // - newly available
constructor(state) { // syntactic sugar for the more
// "class like" inheritance pattern.
super(state);
withDesktopSpecificGetters.call(this, state); // - applying a "stateful mixin"
} // at instance/object level.
}
withDesktopSpecificMeasures.call(Desktop.prototype); // - making use of inheritance via the
// constructor's prototype, but enriching the
// latter by a more generic mixin (at "class level").
let
desktop = new Desktop({
manufacturer: "JAR Computers",
processorSpeed: 3.3,
ram: 8,
hardDiskSpace: 1,
bodyWidth: 300,
bodyHeight: 40,
bodyLength: 300
});
console.log("Desktop.prototype : ", Desktop.prototype);
console.log("Computer.prototype : ", Computer.prototype);
console.log("(desktop instanceof Desktop) ? ", (desktop instanceof Desktop));
console.log("(desktop instanceof Computer) ? ", (desktop instanceof Computer));
console.log("desktop.manufacturer : ", desktop.manufacturer);
console.log("desktop.processorSpeed : ", desktop.processorSpeed);
console.log("desktop.ram : ", desktop.ram);
console.log("desktop.hardDiskSpace : ", desktop.hardDiskSpace);
console.log("desktop.getQuality() : ", desktop.getQuality());
console.log("desktop.getBodyVolume() : ", desktop.getBodyVolume());
console.log("desktop.valueOf() : ", desktop.valueOf());
console.log("desktop.toString() : ", desktop.toString());
One might consider having a look at a much better JavaScript example too, that also tries to demonstrate when to use inheritance via class extension and when not, when to use just mixin/trait based composition and also when to use both.
side note - recommended resources on functions based Mixins / Traits / Talents in JavaScript
Additionally I do recommend reading some of the listed answers of mine given on SO, that are related to this topic too.