我有一个现有的原型层次结构,我想对其进行修改,以便保持层次结构完整,但在其末尾添加了一个额外的原型。instanceof
应该对所有原型返回 true。
即:假设我有 B->A,我想将其设为 B->A->Base。现在instanceof
对于 A、B、Base 应该返回 true。
我尝试使用 B.prototype.prototype 和 Object.setPrototypeOf(),但在这两种情况下都没有运气。
使用 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
这表明B到A的继承关系;
console.log(Object.getPrototypeOf(B.prototype) === A.prototype);
因此,考虑到这一点;
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!"); }
}
如果不引用A,你需要这个;
Object.setPrototypeOf(Object.getPrototypeOf(B.prototype), Base.prototype);
这样;
console.log(new A() instanceof Base); // true
console.log(new B() instanceof Base); // true
(new B()).doBase(); // this is the base!
怎么样?玩它here https://jsfiddle.net/Lnjjmpgk/5/.
正如 Bergi 所提到的,要完成Object.setPrototypeOf(A,Base)
以与不引用 A 的类扩展相同的方式,Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)
。 (需要对此进行调查,报告说它会导致循环继承错误......)
延长测试here https://jsfiddle.net/Lnjjmpgk/7/执行类构造函数继承,如上所示。适用于 Chrome 53 (V8 5.3.332.45)。
编辑:注意,这是对继承链进行猴子修补。对于性能而言,这并不是一个好主意。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)