Check if object is a 'direct instance' of a class

前端 未结 6 770
梦毁少年i
梦毁少年i 2021-01-04 13:26

I have two classes:

class Bar extends Foo { // Foo isn\'t relevant
  constructor(value) {
    if (!(value instanceof Foo)) throw \"InvalidArgumentException:          


        
相关标签:
6条回答
  • 2021-01-04 14:00

    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: (...)';
    
    0 讨论(0)
  • 2021-01-04 14:09

    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)
    
    0 讨论(0)
  • 2021-01-04 14:13

    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);

    0 讨论(0)
  • 2021-01-04 14:16

    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: (...)";
    
    0 讨论(0)
  • 2021-01-04 14:16

    If you know all of your classes you can use

    if(!(value instanceof Foo && !(value instanceof Bar) && !(value instanceof Baz)))
    
    0 讨论(0)
  • 2021-01-04 14:21

    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;
    
    0 讨论(0)
提交回复
热议问题