Given this:
function SomeType () { return this; }
How am I able to check an object's type with only a String?
It's all good if I have a reference to the constructor, like so:
new SomeType() instanceof SomeType; // true
But if I want to check the type as a String, there is no easy way to check.
new SomeType() instanceof 'SomeType'; // TypeError
I could inspect the constructor after it is converted to a String:
function SomeType () { return this; }
/function \bSomeType\b/.test( String(new SomeType().constructor) ); // true
But it doesn't work in all scenarios:
var SomeType = function () { return this; }
/function \bSomeType\b/.test( String(new SomeType().constructor) ); // false
Any thoughts on this? Would attempting to validate a type/constructor by-way-of a String be considered an anti-pattern?
2 Answers 2
How about to compare it to window object?
new SomeType() instanceof window['SomeType']; // true
1 Comment
function SomeType () { return this; }
and
var SomeType = function () { return this; };
are very different statements. The first is a function declaration, hoisted before the execution of the script and available throughout the scope of its definition. The latter is a function expression, assigning an unnamed and anonymous function to the variable SomeType.
Trying to match the string "SomeType" in the first case is as simple as parsing the object's constructor as a string (new SomeType().constructor.toString()). In the latter case, SomeType carries a very different meaning: it is the name of a variable storing an anonymous function. You need an entirely different approach to get the name of an object's instance variable, such as performing a for..in loop through a parent object to get its property names.
You should carefully re-examine your code if it's been written with the assumption that function declarations and function expressions are functionally identical.
If you can get by with only checking function declarations (and not names of variables containing function expressions), here's a viable approach:
function isType(obj,name){
var constructor = obj.constructor.toString();
return constructor.slice(9,constructor.indexOf("("))===name;
}
2 Comments
obj.constructor.toString() to have better performance than String(obj.constructor). In my experience, RegEx also tends to be poorly optimized in the current generation of browsers, but that may change in the future. Here's a jsperf to fiddle with the options: jsperf.com/stringifyingaconstructor
var SomeType = function () { ... };; that constructor doesn’t have a name, so you can’t check it.