1

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
  • 1
    “Would attempting to validate a type/constructor by-way-of a String be considered an anti-pattern?” Yes. It’s also not possible, as you’ve seen with var SomeType = function () { … };; that constructor doesn’t have a name, so you can’t check it. Commented May 26, 2015 at 15:39
  • @minitech I figured as much. I love JavaScript's loose typing, until it hurts me. Commented May 26, 2015 at 15:48

2 Answers 2

1

How about to compare it to window object?

new SomeType() instanceof window['SomeType']; // true
Sign up to request clarification or add additional context in comments.

1 Comment

I thought of this, but this will be running inside a heavily modularised Node application, where the original constructor will be out of scope.
0
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

I appreciate the crux of your answer, and I'm already aware of the differences between anonymous/named functions; but my use-case is quite nuanced. Also, your approach for the named function is essentially the same as the one I've already outlined in my question.
You're right, it's just a different way of getting to the same piece of information. But I think you'll find 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.