Skip to content

Instantly share code, notes, and snippets.

@MikeDigitize
Last active September 7, 2016 12:45
Show Gist options
  • Save MikeDigitize/68e7ee3d51c557684952e37cf94b1de9 to your computer and use it in GitHub Desktop.
Save MikeDigitize/68e7ee3d51c557684952e37cf94b1de9 to your computer and use it in GitHub Desktop.
How to bolt on mixins to a base class in ES2015
// combine properties to base prototype
function Combine(target, fns = []) {
let protoCopy = Object.assign(target.prototype);
let extendedProto = (Array.isArray(fns) ? fns : [fns]).reduce((proto, fn) => {
Object.getOwnPropertyNames(fn.prototype).forEach(prop => {
if(!(protoCopy.hasOwnProperty(prop))) {
proto[prop] = fn.prototype[prop];
}
});
return proto;
}, protoCopy);
target.prototype = Object.assign(extendedProto);
return target;
}
// base class
class ABC {
constructor(a) {
this.a = a;
}
methABC() {
return `ABC ${this.a}`;
}
}
class A {
methA() {
return `A ${this.a}`;
}
}
class B {
methB() {
return `B ${this.a}`;
}
}
class C {
methC() {
return `C ${this.a}`;
}
}
class D {
init(value) {
this.sharedProp = value;
}
methD() {
return `D ${this.sharedProp}`;
}
}
class E extends D{
methE() {
return `E ${this.sharedProp }`;
}
}
// practical usage - compose from whatever functionality needed
// export var ComboClass = Combine(ABC, [A, B, C]);
var abc = new (Combine(ABC, [A, B, C]))(10);
console.log(abc.methC()); // C 10
var ab = new (Combine(ABC, [A, B]))(10);
console.log(ab.methB()); // B 10
var a = new (Combine(ABC, A))(10);
console.log(a.methA()); // A 10
var baseClassOnly = new (Combine(ABC))(10);
console.log(baseClassOnly.methABC()); // ABC 10
var d = new (Combine(ABC, [A, B, C, D]))(10);
d.init(100)
console.log(d.methD()); // D 100
var e = new (Combine(ABC, [A, B, C, E]))(10);
e.init(100);
console.log(e.methE()); // E 100
var _e = new (Combine(ABC, [A, B, C, E]))(10);
console.log(_e.methE()); // undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment