Skip to content

Instantly share code, notes, and snippets.

@zhirzh
Created February 8, 2018 15:59
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhirzh/fbfe28ca0f33f14f22a025c914f1d0e3 to your computer and use it in GitHub Desktop.
Save zhirzh/fbfe28ca0f33f14f22a025c914f1d0e3 to your computer and use it in GitHub Desktop.
Multiple Inheritance in JS
function inheritsObject(baseObject, superObject) {
Object.setPrototypeOf(baseObject, superObject);
}
function inheritsMultipleObjects(baseObject, superObjects) {
inheritsObject(
baseObject,
new Proxy({}, {
get(target, key, rec) {
const parent = superObjects.find(p => Reflect.has(p, key));
if (parent !== undefined) {
return Reflect.get(parent, key);
}
return undefined;
},
has(target, key) {
const parentHasKey = superObjects.some(p => Reflect.has(p, key));
if (parentHasKey) {
return true;
}
return false;
}
})
);
}
function inheritsMultipleConstructors(BaseCtor, SuperCtors) {
return new Proxy(BaseCtor, {
construct(_, [baseArgs = [], superArgs = []], newTarget) {
let instance = {};
instance = SuperCtors.reduce((acc, Ctor, i) => {
const args = superArgs[i] || [];
return Object.assign(acc, new Ctor(...args));
}, instance);
instance = Object.assign(instance, new BaseCtor(...baseArgs));
inheritsObject(instance, BaseCtor.prototype);
return instance;
}
});
}
function inheritsMultiple(BaseCtor, SuperCtors) {
inheritsMultipleObjects(
BaseCtor.prototype,
SuperCtors.map(Ctor => Ctor.prototype)
);
return inheritsMultipleConstructors(BaseCtor, SuperCtors);
}
/*// C ->> B -> A
class A {
constructor(x) {
this.A = x;
}
}
class B extends A {
constructor(x, y) {
super(y);
this.B = x;
}
}
class _C {
constructor(x) {
this.C = x;
}
}
const C = inheritsMultipleConstructors(_C, [B]);
const a = new A(1);
console.log(a);
console.log(a.A);
const b = new B(2, 1);
console.log(b);
console.log(b.A);
console.log(b.B);
const c = new C([3], [[2, 1]]);
console.log(c);
console.log(c.A);
console.log(c.B);
console.log(c.C);*/
/*// C -> B ->> A
class A {
constructor(x) {
this.A = x;
}
}
class _B {
constructor(x) {
this.B = x;
}
}
const B = inheritsMultipleConstructors(_B, [A]);
class C extends B {
constructor(x, y, z) {
super(y, z);
this.C = x;
}
}
const a = new A(1);
console.log(a);
console.log(a.A);
const b = new B([2], [[1]]);
console.log(b);
console.log(b.A);
console.log(b.B);
const c = new C(3, [2], [[1]]);
console.log(c);
console.log(c.A);
console.log(c.B);
console.log(c.C);*/
/*// C ->> B ->> A
class _A {
constructor(x) {
this.A = x;
}
}
const A = inheritsMultipleConstructors(_A, []);
class _B {
constructor(x) {
this.B = x;
}
}
const B = inheritsMultipleConstructors(_B, [A]);
class _C {
constructor(x) {
this.C = x;
}
}
const C = inheritsMultipleConstructors(_C, [B]);
const a = new A([1], []);
console.log(a);
console.log(a.A);
const b = new B([2], [[[1]]]);
console.log(b);
console.log(b.A);
console.log(b.B);
const c = new C([3], [[[2], [[[1]]]]]);
console.log(c);
console.log(c.A);
console.log(c.B);
console.log(c.C);*/
/*const a = {};
const b = {a: 1};
const c = {};
const d = {};
const e = {};
const f = {}
const g = {};
inheritsObject(f, c);
inheritsMultipleObjects(e, [a, b]);
inheritsMultipleObjects(g, [e, f, d]);
console.log(g.a); // 1*/
/*// C ->> B -> A
const A = {
AA() {
return 'AA';
}
};
const B = {
BB() {
return 'BB';
}
};
inheritsObject(B, A);
const C = {
CC() {
return 'CC';
}
};
inheritsMultipleObjects(C, [B]);
const x = Object.create(C);
console.log(x);
console.log(x.AA());
console.log(x.BB());
console.log(x.CC());*/
/*// C -> B ->> A
const A = {
AA() {
return 'AA';
}
};
const B = {
BB() {
return 'BB';
}
};
inheritsMultipleObjects(B, [A]);
const C = {
CC() {
return 'CC';
}
};
inheritsObject(C, B);
const x = Object.create(C);
console.log(x);
console.log(x.AA());
console.log(x.BB());
console.log(x.CC());*/
/*// C ->> B ->> A
const A = {
AA() {
return 'AA';
}
};
const B = {
BB() {
return 'BB';
}
};
inheritsMultipleObjects(B, [A]);
const C = {
CC() {
return 'CC';
}
};
inheritsMultipleObjects(C, [B]);
const x = Object.create(C);
console.log(x);
console.log(x.AA());
console.log(x.BB());
console.log(x.CC());*/
/*// C ->> B -> A
class A {
constructor(x) {
this.A = x;
}
AA() {
return this.A + this.A;
}
}
class B extends A {
constructor(x, y) {
super(y);
this.B = x;
}
BB() {
return this.B + this.B;
}
}
class _C {
constructor(x) {
this.C = x;
}
CC() {
return this.C + this.C;
}
}
const C = inheritsMultiple(_C, [B]);
const a = new A(1);
console.log(a);
console.log(a.AA());
const b = new B(2, 1);
console.log(b);
console.log(b.AA());
console.log(b.BB());
const c = new C([3], [[2, 1]]);
console.log(c);
console.log(c.AA());
console.log(c.BB());
console.log(c.CC());*/
/*// C -> B ->> A
class A {
constructor(x) {
this.A = x;
}
AA() {
return this.A + this.A;
}
}
class _B {
constructor(x) {
this.B = x;
}
BB() {
return this.B + this.B;
}
}
const B = inheritsMultiple(_B, [A]);
class C extends B {
constructor(x, y, z) {
super(y, z);
this.C = x;
}
CC() {
return this.C + this.C;
}
}
const a = new A(1);
console.log(a);
console.log(a.AA());
const b = new B([2], [[1]]);
console.log(b);
console.log(b.AA());
console.log(b.BB());
const c = new C(3, [2], [[1]]);
console.log(c);
console.log(c.AA());
console.log(c.BB());
console.log(c.CC());*/
/*// C ->> B ->> A
class _A {
constructor(x) {
this.A = x;
}
AA() {
return this.A + this.A;
}
}
const A = inheritsMultiple(_A, []);
class _B {
constructor(x) {
this.B = x;
}
BB() {
return this.B + this.B;
}
}
const B = inheritsMultiple(_B, [A]);
class _C {
constructor(x) {
this.C = x;
}
CC() {
return this.C + this.C;
}
}
const C = inheritsMultiple(_C, [B]);
const a = new A([1], []);
console.log(a);
console.log(a.AA());
const b = new B([2], [[[1]]]);
console.log(b);
console.log(b.AA());
console.log(b.BB());
const c = new C([3], [[[2], [[[1]]]]]);
console.log(c);
console.log(c.AA());
console.log(c.BB());
console.log(c.CC());*/
@dev-zetta
Copy link

multiple-inheritance.js - Line 45 should be:

inheritsObject(instance, newTarget.prototype);

According your acticle:
https://itnext.io/multiple-inheritance-in-js-part-2-24adca2c2518

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment