// - the foolowing functions do implement each
// a function-based "stateful mixin" which
// preserves injected local state by creating
// a closure at call/apply time.
// - targeting the introspection of local state.
function withLocalStateIntrospection(state) {
function valueOf () {
return { ...state };
};
function toString () {
return JSON.stringify(state);
};
Object.defineProperties(this, {
valueOf: { value: valueOf },
toString: { value: toString },
});
}
// - targeting hardware specific state getters.
function withHardwareStandardGetters(state) {
Object.defineProperties(this, {
manufacturer: { enumerable: true, get: () => state.manufacturer },
processorSpeed: { enumerable: true, get: () => state.processorSpeed },
ram: { enumerable: true, get: () => state.ram },
hardDiskSpace: { enumerable: true, get: () => state.hardDiskSpace },
});
}
// - targeting desktop specific state getters.
function withDesktopSpecificGetters(state) {
Object.defineProperties(this, {
bodyWidth: { enumerable: true, get: () => state.bodyWidth },
bodyHeight: { enumerable: true, get: () => state.bodyHeight },
bodyLength: { enumerable: true, get: () => state.bodyLength },
});
}
// - the foolowing functions do implement each a
// simple (no state handling) function-based mixin.
// - targeting hardware specific quality parameters.
function withHardwareSpecificQuality() {
function getQuality () {
return this.processorSpeed * this.ram * this.hardDiskSpace;
};
function isFast () {
return this.processorSpeed > (this.ram / 4);
};
function isRoomy () {
return this.hardDiskSpace > Math.floor(this.ram * this.processorSpeed);
};
Object.defineProperties(this, {
getQuality: { value: getQuality },
isFast: { value: isFast },
isRoomy: { value: isRoomy },
});
}
// - targeting desktop specific measures.
function withDesktopSpecificMeasures() {
function getBodyVolume() {
return this.bodyLength * this.bodyWidth * this.bodyHeight;
};
Object.defineProperty(this, 'getBodyVolume', { value: getBodyVolume });
}
// - examples of
//
// - function based object composition
// - at instance/object level,
// - at class level.
//
// - sub-classing
// - base/super class
class Computer {
constructor(state) {
// - applying 2 "stateful mixin"
// at instance/object level.
withLocalStateIntrospection.call(this, state);
withHardwareStandardGetters.call(this, state);
}
}
// - making use of inheritance via the constructor's
// prototype, but augmenting the latter by a more
// generic mixin at class level.
withHardwareSpecificQuality.call(Computer.prototype);
// - derieved class / sub-classing
class Desktop extends Computer {
constructor(state) {
super(state);
// - applying a "stateful mixin"
// at instance/object level.
withDesktopSpecificGetters.call(this, state);
}
}
// - making use of inheritance via the constructor's
// prototype, but augmenting the latter by a more
// generic mixin at class level.
withDesktopSpecificMeasures.call(Desktop.prototype);
const desktop = new Desktop({
manufacturer: "JAR Computers",
processorSpeed: 3.3,
ram: 8,
hardDiskSpace: 1,
bodyWidth: 300,
bodyHeight: 40,
bodyLength: 300
});
console.log(
"(desktop instanceof Desktop) ?",
(desktop instanceof Desktop)
);
console.log(
"(desktop instanceof Computer) ?",
(desktop instanceof Computer)
);
console.log("Object.keys(desktop) :", Object.keys(desktop));
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.isFast() :", desktop.isFast());
console.log("desktop.isRoomy() :", desktop.isRoomy());
console.log("desktop.getQuality() :", desktop.getQuality());
console.log("desktop.getBodyVolume() :", desktop.getBodyVolume());
console.log("desktop.valueOf() :", desktop.valueOf());
console.log("desktop.toString() :", desktop.toString());
console.log(
"\nObject.getOwnPropertyDescriptors(Desktop.prototype)) :",
Object.getOwnPropertyDescriptors(Desktop.prototype)
);
console.log(
"\nObject.getOwnPropertyDescriptors(Computer.prototype)) :",
Object.getOwnPropertyDescriptors(Computer.prototype)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }