Reputation: 17864
I have a js object that could be a function or a class, ie. it is equal to one of:
class {
constructor( param ) { }
onCreate() { }
};
Or,
function ( param ) { };
Turns out they have more in common then I expected (eg. both have a constructor). Please tell me the simplest way to determine which of these types my js object refers to.
The solution must work in node 4.3.2.
edit: To clarify, the object that I'm trying to differentiate is a class or a function, not an instance of these. And yes, I'm aware that a class is just syntatic sugar, that's what is making this difficult.
Upvotes: 1
Views: 244
Reputation: 46599
The answer to these sorts of questions is almost always Lodash (or Underscore). Lodash has isFunction:
Checks if value is classified as a Function object.
There are a TON of things in Lodash that people try to re-create all the time. Lodash is almost certainly doing it the right way and it's well-maintained.
Moral of the story: check if Lodash does X before you write a function to do X.
coffee> ld.isFunction
[Function: isFunction]
coffee> ld.isFunction(Date)
true
coffee> a = b:2
{ b: 2 }
coffee> ld.isFunction(a)
false
coffee>
coffee> d = new Date()
2016-12-17T00:02:58.950Z
coffee> ld.isFunction(d)
false
Upvotes: 0
Reputation: 17864
I thought it worth adding that, if one knows the names of the class or function, you can distinguish them like this.
> const C = class CC { };
undefined
> const F = function FF() { };
undefined
> C.prototype
CC {}
> F.prototype
FF {}
And if they are anonymous (not sure if that terminology is used in js) then you get just '{}'.
In a program you can use util.inspect (the name part dissapears with toString) to get at these strings.
Upvotes: 0
Reputation: 55749
A class
is not a "real thing" in the JavaScript specification beyond being syntactic sugar for the composition of pre-existing language primitives.
Vendors may make distinction possible (e.g. the toString
method suggested in another answer), but I have scanned the spec and I don't think that is part of it... so is vendor-defined and therefore cannot be relied upon.
Indeed: Firefox 50 on the Mac does not print the word "class" (it uses the word "function") when toString
is used on a class
.
I don't know much about JS classes, so I could be wrong...
Upvotes: 2
Reputation: 94111
I get this in the REPL with v6.9.2:
λ node -i
> class A {}
[Function: A]
> let B = function() {}
undefined
> A.toString()
'class A {}'
> B.toString()
'function () {}'
There may be another more reliable way, but checking for class
should work:
if (A.toString().match(/^class/)) {
// it's a class
}
Upvotes: 1