几年前,我想弄清楚如何为类
A
创建类型检查,并为由 true
实例化的对象返回 new A()
only。为此,我这样写了这个类:
class A {
static #instances = new WeakSet();
static isInstance (value) {
return A.#instances.has(value);
}
constructor () {
if (new.target === A) {
A.#instances.add(this);
}
}
}
扩展
A
的类的任何实例在传递给 false
时都会返回 A.isInstance
。但是,后来我意识到这可以通过使用Reflect.construct(B, [], A)
来伪造。然后,我所做的是创建一个代理,如果满足某些条件,其 construct
陷阱只会将 A
作为 newTarget
传递。我一直在尝试回忆那个条件是什么,但在尝试重新发现它时,我开始认为我的旧解决方案可能不起作用。
这里有什么方法可以达到我想要的效果吗?
似乎没有明显的干净方法来做到这一点
Reflect.construct
来捕捉原型被覆盖的情况class A {
static #instances = new WeakSet();
static isInstance (value) {
return A.#instances.has(value);
}
constructor() {
if (new.target === A) {
try{
throw new Error;
}catch(e){
// parse function names (in FF the stack is different)
const [a, b] = e.stack.match(/\w+(?=\s*\()/gm);
const fn = eval(b);
if(fn?.toString().includes('extends A')) return;
}
A.#instances.add(this);
}
}
}
class B extends A{}
const b = Reflect.construct(B, [], A);
console.log(A.isInstance(b));
const a = new A;
console.log(A.isInstance(a));