javascript - Determine closest ancestor between list of classes
问题描述
Consider this example:
class Point {}
class Point2D extends Point {}
class Point3D extends Point2D {}
class FloatPoint extends Point {}
class Bar {}
class Foo extends Bar {}
const result = joinWithClosestAncestor([Point, Point2D, Point3D, FloatPoint, Bar, Foo])
// result === [[Point], [Point2D, Point], [Point3D, Point2D], [FloatPoint, Point], [Bar], [Foo, Bar]];
I'm trying to create joinWithClosestAncestor
which takes an array of classes and returns an array of pairs where the first element is the class & the second is the closest ancestor of the class (if any) from the input classes.
In the example Point3D
is derived from Point
through Point2D
, but because Point2D
is in the input list & is closer related to Point3D
than Point
, it is instead chosen. I can use Class.prototype instanceof X
to determine if it's related or not but I can't compare the depth
of the relation.
Is there a way to somehow compare the depth
of instanceof
between different classes to always get the CLOSEST relation? Or any other way?
解决方案
您可以Object.getPrototypeOf()
在类构造函数上使用来获取其直接超类构造函数。它找不到明显的 MDN 源代码,但Axel Rauschmayer 博士为不耐烦的程序员编写的 JavaScript解释说,发生这种情况是为了让static
子类继承属性和方法。
无论如何,由于您可以找到直接的超类构造函数,因此您可以沿着该链向上走,直到找到存在于您的数组中的某些东西,或者直到您离开链的末端。像这样的东西,例如:
function joinWithClosestAncestor(ctors: Array<new (...args: any) => any>) {
const ret = [];
for (let ctor of ctors) {
const cur = [ctor];
ret.push(cur);
for (
let parent = Object.getPrototypeOf(ctor);
parent;
parent = Object.getPrototypeOf(parent)
) {
if (ctors.includes(parent)) {
cur.push(parent);
break;
}
}
}
return ret;
}
它产生了您正在寻找的结果,至少对于您给出的示例:
const result = joinWithClosestAncestor([Point, Point2D, Point3D, FloatPoint, Bar, Foo])
console.log(JSON.stringify(result.map(x => x.map(y => y.name))));
// [["Point"],["Point2D","Point"],["Point3D","Point2D"],
// ["FloatPoint","Point"],["Bar"],["Foo","Bar"]]
推荐阅读
- python - Sagemaker LDA 主题模型 - 如何访问训练模型的参数?还有一种简单的方法来捕捉连贯性
- java - 带有 Java Sprint Boot REST 的 Google App Engine Standard - 在 GCLOUD 服务器中不起作用
- powershell - Get-AzureKeyVaultSecret : Unable to retrieve service key for ServicePrincipal account
- javascript - 无法提交表单 - ReactJs
- google-maps - 如何一次只显示一种类型的谷歌地图标记
- google-chrome - Chrome 扩展程序可以从安装的其他 chrome 扩展程序访问数据(chrome.storage API)吗?
- excel - 处理表格时的 Excel 动态数据验证选项
- html - 如何在 jquery 表的搜索栏中禁用 chrome 自动完成功能
- ruby-on-rails - 如何在 Rails 中实现条码生成器
- python - 分发在黑暗中如何运作?