0

I'd like to check the class of an object, such as this:

class Foo {}
var foo = new Foo();

I saw this post In ES6, how do you check the class of an object? that correctly says I can use

if (foo instanceof Foo) { ... }

Is there a way to do this without having to require every class I want to check for into the file? If I am doing it with foo instanceof Foo, for lots of classes, I have to require each one into the file (often for only that purpose).

Is there another way?

Sir Robert
  • 4,686
  • 7
  • 41
  • 57
  • 5
    foo.contructor.name should work in ES6 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name) – angrykoala May 26 '17 at 15:50
  • 2
    If you're checking for a lot of different classes, then you are probably writing poor code that could be coded in a much more object oriented way without comparing ANY specific class name. You should not need to do what you're trying to do if you have an appropriate object oriented class design and use polymorphism or even duck typing to your advantage. – jfriend00 May 26 '17 at 16:01
  • @jfriend00 Thanks(ish) for the input. The code isn't poor, it's that I'm writing a very task-specific harness for internal use that makes use of domain-specific code that needs to be packaged separately. angrykoala had a helpful technical tip. – Sir Robert May 26 '17 at 17:43
  • 1
    If you show what you're actually trying to accomplish, I'd wager that there are significantly better ways to do it that do not need to test a class type. Just because you may have found a work-around does not mean that it's actually the best way to accomplish whatever it is you're trying to accomplish. Lots of tests with `instanceof` or using `.name` are usually a failure to use the advantages of object oriented design as intended. – jfriend00 May 26 '17 at 17:47

1 Answers1

0

The class is involved by this check, hence it should be imported. Importing classes and checking against them with instanceof is semantically correct way that leaves no space for error.

It is possible to check against class name. There are no guarantees, but it can be done. This won't work if Node application is minified or obfuscated for some reason. This won't work if there are different classes with same name.

For shallow check if an object was directly instantiated from a class it is just

if (foo.constructor && foo.constructor.name === 'Foo') ...

For deep check the entire prototype chain should be traversed (this is what instanceof does):

function isInstance(proto, className) {
    do {
        if (proto && proto.constructor && proto.constructor.name === className)
            return true;
    } while (proto = Object.getPrototypeOf(proto));

    return false;
}

if (isInstance(obj, 'Foo')) ...
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Yeah, I had the same rationale myself. I realized that one of the potential failures of this would be that a class from some other module with the same name would be a 'false positive.' Nonetheless, it seemed like a good academic question (at least). This is the right answer (because it both answers the question, providing better insight into how node works) and because it provides the correct specific insight into why it is not the preferred solution. – Sir Robert May 27 '17 at 03:49