检查对象是否是 class 的 'direct instance'
Check if object is a 'direct instance' of a class
我有两个类:
class Bar extends Foo { // Foo isn't relevant
constructor(value) {
if (!(value instanceof Foo)) throw "InvalidArgumentException: (...)";
super();
this.value = value;
}
}
class Baz extends Bar {
constructor(value) {
super(value);
}
}
Bar
constructor
检查 value
是否是 Foo 的实例,如果不是则抛出错误。至少,那是我想要它做的。如果您传递 Bar
或 Baz
作为值,if 语句 returns true
也是如此。目标是只让Foo
通过。
我已经找到了 this answer,但这并没有真正回答我的问题。
如果您知道所有 类 您可以使用
if(!(value instanceof Foo && !(value instanceof Bar) && !(value instanceof Baz)))
检查构造函数:
if (!value || value.constructor !== Foo)
throw 'InvalidArgumentException: (...)';
或对象的原型(这更类似于instanceof
所做的):
if (!value || Object.getPrototypeOf(value) !== Foo.prototype)
throw 'InvalidArgumentException: (...)';
问题是您引用的所有 类 都是 Foo
的后代。这样 new Baz() instanceOf Bar && new Bar() instanceOf Foo === true
。
所以当你问是Bar instanceOf Foo时,通过继承它会是真的。
由于 JS 中没有 Java getClass()
等价物,您应该使用类似的东西:
if (value.constructor.name !== Foo.name)
您可以使用 Object.getPrototypeOf(yourObj)
和 Foo.prototype
之间的比较来查看 yourObj
是否恰好是 Foo
的实例。您可以通过继续为每个级别调用 Object.getPrototypeOf
来向上移动链。
示例:
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}
const foo = new Foo();
const bar = new Bar();
const baz = new Baz();
// For this function:
// - level 0 is self
// - level 1 is parent
// - level 2 is grandparent
// and so on.
function getPrototypeAt(level, obj) {
let proto = Object.getPrototypeOf(obj);
while (level--) proto = Object.getPrototypeOf(proto);
return proto;
}
console.log("bar is a foo:", bar instanceof Foo);
console.log("baz is a foo:", baz instanceof Foo);
console.log("foo is exactly a foo:", getPrototypeAt(0, foo) === Foo.prototype);
console.log("bar is exactly a foo:", getPrototypeAt(0, bar) === Foo.prototype);
console.log("bar is direct child of foo:", getPrototypeAt(1, bar) === Foo.prototype);
console.log("baz is direct child of foo:", getPrototypeAt(1, baz) === Foo.prototype);
console.log("baz is direct child of bar:", getPrototypeAt(1, baz) === Bar.prototype);
console.log("baz is grandchild of foo:", getPrototypeAt(2, baz) === Foo.prototype);
您应该测试 value
的内部 [[Prototype]]
是否恰好是 Foo.prototype
。您可以使用 Object.getPrototypeOf 获得内部 [[Prototype]]
:
if ( Object.getPrototypeOf( value ) !== Foo.prototype )
throw "InvalidArgumentException: (...)";
我创造了检查 DOM 类 和元素
之间关系的函数
const getCreator = instance => Object.getPrototypeOf(instance).constructor.name;
// usage
getCreator(document.documentElement) === "HTMLHtmlElement;
我有两个类:
class Bar extends Foo { // Foo isn't relevant
constructor(value) {
if (!(value instanceof Foo)) throw "InvalidArgumentException: (...)";
super();
this.value = value;
}
}
class Baz extends Bar {
constructor(value) {
super(value);
}
}
Bar
constructor
检查 value
是否是 Foo 的实例,如果不是则抛出错误。至少,那是我想要它做的。如果您传递 Bar
或 Baz
作为值,if 语句 returns true
也是如此。目标是只让Foo
通过。
我已经找到了 this answer,但这并没有真正回答我的问题。
如果您知道所有 类 您可以使用
if(!(value instanceof Foo && !(value instanceof Bar) && !(value instanceof Baz)))
检查构造函数:
if (!value || value.constructor !== Foo)
throw 'InvalidArgumentException: (...)';
或对象的原型(这更类似于instanceof
所做的):
if (!value || Object.getPrototypeOf(value) !== Foo.prototype)
throw 'InvalidArgumentException: (...)';
问题是您引用的所有 类 都是 Foo
的后代。这样 new Baz() instanceOf Bar && new Bar() instanceOf Foo === true
。
所以当你问是Bar instanceOf Foo时,通过继承它会是真的。
由于 JS 中没有 Java getClass()
等价物,您应该使用类似的东西:
if (value.constructor.name !== Foo.name)
您可以使用 Object.getPrototypeOf(yourObj)
和 Foo.prototype
之间的比较来查看 yourObj
是否恰好是 Foo
的实例。您可以通过继续为每个级别调用 Object.getPrototypeOf
来向上移动链。
示例:
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}
const foo = new Foo();
const bar = new Bar();
const baz = new Baz();
// For this function:
// - level 0 is self
// - level 1 is parent
// - level 2 is grandparent
// and so on.
function getPrototypeAt(level, obj) {
let proto = Object.getPrototypeOf(obj);
while (level--) proto = Object.getPrototypeOf(proto);
return proto;
}
console.log("bar is a foo:", bar instanceof Foo);
console.log("baz is a foo:", baz instanceof Foo);
console.log("foo is exactly a foo:", getPrototypeAt(0, foo) === Foo.prototype);
console.log("bar is exactly a foo:", getPrototypeAt(0, bar) === Foo.prototype);
console.log("bar is direct child of foo:", getPrototypeAt(1, bar) === Foo.prototype);
console.log("baz is direct child of foo:", getPrototypeAt(1, baz) === Foo.prototype);
console.log("baz is direct child of bar:", getPrototypeAt(1, baz) === Bar.prototype);
console.log("baz is grandchild of foo:", getPrototypeAt(2, baz) === Foo.prototype);
您应该测试 value
的内部 [[Prototype]]
是否恰好是 Foo.prototype
。您可以使用 Object.getPrototypeOf 获得内部 [[Prototype]]
:
if ( Object.getPrototypeOf( value ) !== Foo.prototype )
throw "InvalidArgumentException: (...)";
我创造了检查 DOM 类 和元素
之间关系的函数const getCreator = instance => Object.getPrototypeOf(instance).constructor.name;
// usage
getCreator(document.documentElement) === "HTMLHtmlElement;