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());
我想你應該如何別的之前使用堆棧溢出片段閱讀...... –
你怎麼定義'Desktop'? 'Computer.prototype'上定義了'ram','processorSpeed'和'hardDiskSpace'?如果沒有,爲什麼你把'computerQualityMixin'作爲'this'值傳遞'Computer.prototype'呢? – Oriol
'Computer.prototype'是空的對象。如果代碼應該按預期工作,應該在構造函數的末尾調用'computerQualityMixin.call(this)'。整個'mixin'的東西看起來很混亂。由於'計算機'沒有父親,我沒有看到爲什麼它不能在自己或父類中定義'getQuality'等方法。 – estus