将 base class 添加到现有原型链,以便 instanceof 工作
Add base class to existing prototype chain so that instanceof works
我有一个现有的原型层次结构,我想修改它以保持层次结构完整,但在它的末尾添加一个额外的原型。 instanceof
应该 return 对于所有原型都是正确的。
即:假设我有 B->A,我想将其设为 B->A->Base。现在 instanceof
对于 A、B、Base 应该 return 为真。
我尝试使用 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.
正如 Bergi 所提到的,要以与 class 扩展相同的方式完成 Object.setPrototypeOf(A,Base)
而无需引用 A,Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)
。 (需要调查这个,报告它导致循环继承错误...)
扩展测试 here 以执行 class 构造函数继承,如上所示。适用于 Chrome 53 (V8 5.3.332.45)。
编辑:注意,这是猴子修补继承链。这对性能来说不是一个好主意。
我有一个现有的原型层次结构,我想修改它以保持层次结构完整,但在它的末尾添加一个额外的原型。 instanceof
应该 return 对于所有原型都是正确的。
即:假设我有 B->A,我想将其设为 B->A->Base。现在 instanceof
对于 A、B、Base 应该 return 为真。
我尝试使用 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.
正如 Bergi 所提到的,要以与 class 扩展相同的方式完成 Object.setPrototypeOf(A,Base)
而无需引用 A,Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)
。 (需要调查这个,报告它导致循环继承错误...)
扩展测试 here 以执行 class 构造函数继承,如上所示。适用于 Chrome 53 (V8 5.3.332.45)。
编辑:注意,这是猴子修补继承链。这对性能来说不是一个好主意。