Ответ 1
Object.getPrototypeOf(Object.getPrototypeOf(foo)).constructor.name;
У меня есть класс и еще один класс, который расширяет этот класс.
class Shape {
constructor() {
return this;
}
}
class Circle extends Shape {
constructor() {
super();
return this;
}
}
let foo = new Circle();
Я могу получить класс foo с
let className = foo.constructor.name
// returns string 'Circle'
Можно ли получить имя суперкласса foo ('Shape') аналогичным образом?
Object.getPrototypeOf(Object.getPrototypeOf(foo)).constructor.name;
Получил это:
let superClassName = foo.__proto__.__proto__.constructor.name
// return Shape
Изменить: это возвращает родительский класс, который не обязательно относится к классу Circle, который был первоначально выполнен. В моем случае использования они одинаковы, но здесь есть тонкая двусмысленность в отношении значения "суперкласса".
Вы можете определить следующий класс:
class MyObject
{
extends(className)
{
let next = Object.getPrototypeOf(this);
while(next.constructor.name !== "Object")
{
if(next.constructor.name === className)
return true;
next = Object.getPrototypeOf(next);
}
return false;
}
}
Пусть каждый определенный вами класс расширяет этот класс.
Теперь, если вы хотите проверить, расширяет ли ваш объект определенный класс, вы можете вызвать его как метод extends и передать в качестве аргумента имя родительского класса. Метод extends будет проходить по всему дереву наследования и проверять, расширяет ли ваш объект данный класс, проверяя не только его родителей, но также его бабушек и дедушек и бабушек и дедушек и т.д.
Пример:
class MyObject
{
extends(className)
{
let next = Object.getPrototypeOf(this);
while(next.constructor.name !== "Object")
{
if(next.constructor.name === className)
return true;
next = Object.getPrototypeOf(next);
}
return false;
}
}
class Vehicle extends MyObject
{
}
class Car extends Vehicle
{
}
class Bmw extends Car
{
}
let car = new Car();
let bmw = new Bmw();
console.log("bmw extends Bmw: " + bmw.extends("Bmw"));
console.log("bmw extends Car: " + bmw.extends("Car"));
console.log("bmw extends Vehicle: " + bmw.extends("Vehicle"));
console.log("car extends Car: " + car.extends("Car"));
console.log("car extends Bmw: " + car.extends("Bmw"));
Ваш конечный суперкласс всегда является Object, поэтому нет смысла пытаться его извлечь. Вам нужно выяснить, является ли рассматриваемый экземпляр экземпляром чего-то другого, используя ключевое слово 'is'. Я пишу это с точки зрения ActionScript-3, поэтому я не уверен, что такое синтаксис в ES-6, но он должен быть в строках "if (this Shape)". Это вернет true, если рассматриваемый экземпляр расширяет класс, о котором вы говорите, false в противном случае.
Однако то, что вы просите, - это то, где Shape отделяется от стандартной библиотеки или стандартного объекта, и компилятор или среда выполнения не могут понять это. Теоретически было бы неплохо, если бы языки ECMA могли дать вам задний массив наследования для данного класса, но AFAIK, который не является и никогда не был функцией. Без полной цепочки наследования вам нужно знать, какой суперкласс вы ищете, или вы не можете получить его каким-либо логическим способом.