I have two classes:
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);
}
}
The Bar
constructor
checks if value
is an instance of Foo, it throws an error if it isn't. At least, that's what I wanted it to do. If you pass a Bar
or a Baz
as value, the if-statement returns true
as well. The goal is to only let Foo
s through.
I found this answer already but that didn't really answer my question.
Check the constructor:
if (!value || value.constructor !== Foo)
throw 'InvalidArgumentException: (...)';
or the prototype of the object (this is more similar to what instanceof
does):
if (!value || Object.getPrototypeOf(value) !== Foo.prototype)
throw 'InvalidArgumentException: (...)';
You can use a comparison between Object.getPrototypeOf(yourObj)
and Foo.prototype
to see if yourObj
is exactly an instance of Foo
. And you can move up the chain by just continuing to call Object.getPrototypeOf
for each level.
Example:
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);
You should test if value
's internal [[Prototype]]
is exactly Foo.prototype
. You can get the internal [[Prototype]]
with Object.getPrototypeOf :
if ( Object.getPrototypeOf( value ) !== Foo.prototype )
throw "InvalidArgumentException: (...)";
如果你知道你可以使用的所有课程
if(!(value instanceof Foo && !(value instanceof Bar) && !(value instanceof Baz)))
The problem is that all of your classes you reference are descendants of Foo
. Such that new Baz() instanceOf Bar && new Bar() instanceOf Foo === true
. So when you ask is Bar instanceOf Foo, it will be true through inheritance.
Due to there being no Java getClass()
equivalent in JS, you should use something like:
if (value.constructor.name !== Foo.name)
I coined the function for checking relationships between DOM Classes and elements
const getCreator = instance => Object.getPrototypeOf(instance).constructor.name;
// usage
getCreator(document.documentElement) === "HTMLHtmlElement;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.