问题
I have an existing prototype hierarchy and I want to modify it so that the hierarchy is kept intact but an additional prototype is added to then end of it. instanceof
should return true for all prototypes.
I.e.: say I have B->A and I want to make it B->A->Base. Now instanceof
should return true for A, B, Base.
I tried using B.prototype.prototype and Object.setPrototypeOf(), but no luck in either case.
Sample with Object.setPrototypeOf():
class A {
do() { console.log("do A"); }
}
class B extends A {
do() { console.log("do B"); }
doB() { console.log("what"); }
}
var a = new A();
var b = new B();
a.do();
b.do();
b.doB();
console.log(a instanceof A) // true
console.log(a instanceof B) // false
console.log(b instanceof A) // true
console.log(b instanceof B) // true
class Base {
doBase() { console.log("this is the base!"); }
}
// now add Base to B's chain, so that B -> A -> Base
// TODO: doesn't work!
Object.setPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(B)), Base.prototype)
//Object.setPrototypeOf(Object.getPrototypeOf(B), Base)
console.log(Object.getPrototypeOf(B))
console.log(Object.getPrototypeOf(Object.getPrototypeOf(B)))
var c = new B();
console.log(c instanceof B) // true
console.log(c instanceof A) // true
console.log(c instanceof Base) // false (!!! how to fix it?)
c.doBase(); // crash, not a function
回答1:
This shows inheritance relationship from B to A;
console.log(Object.getPrototypeOf(B.prototype) === A.prototype);
So, given this;
class A { do() { console.log("do A"); } }
class B extends A {
do() { console.log("do B"); }
doB() { console.log("what"); }
}
class Base {
doBase() { console.log("this is the base!"); }
}
Without referencing A, you need this;
Object.setPrototypeOf(Object.getPrototypeOf(B.prototype), Base.prototype);
Such that;
console.log(new A() instanceof Base); // true
console.log(new B() instanceof Base); // true
(new B()).doBase(); // this is the base!
How's that? Play with it here.
As mentioned by Bergi, to accomplish Object.setPrototypeOf(A,Base)
in the same manner as class extension without referencing A, Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)
. (Need to investigate this, reported that it causes a cyclic inheritance error...)
Extended the test here to perform the class constructor inheritance as shown above. Works in Chrome 53 (V8 5.3.332.45).
Edit: Note, this is monkey-patching the inheritance chain. It's not a fantastic idea for performance.
来源:https://stackoverflow.com/questions/39691276/add-base-class-to-existing-prototype-chain-so-that-instanceof-works