Добавьте базовый класс в существующую цепочку прототипов, чтобы instanceof работал
У меня есть существующая иерархия прототипов, и я хочу изменить ее так, чтобы иерархия оставалась нетронутой, но к ее концу добавлялся дополнительный прототип. instanceof
должен вернуть true для всех прототипов.
То есть: скажем, у меня есть B->A и я хочу сделать это B->A->Base. Сейчас instanceof
должен вернуть true для A, B, Base.
Я пытался использовать 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
1 ответ
Это показывает отношения наследования от 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!"); }
}
Без ссылки на А вам это нужно;
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!
Как это? Играть с этим здесь.
Как упомянуто Берги, чтобы выполнить Object.setPrototypeOf(A,Base)
таким же образом, как расширение класса без ссылки на A, Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)
, (Нужно исследовать это, сообщил, что это вызывает ошибку циклического наследования...)
Здесь расширен тест для выполнения наследования конструктора класса, как показано выше. Работает в Chrome 53 (V8 5.3.332.45).
Изменить: Обратите внимание, это обезьяна-патчирование цепочки наследования.Это не фантастическая идея для производительности.