64

How can I check if my javascript object is of a certain type.

var SomeObject = function() { }
var s1 = new SomeObject();

In the case above typeof s1 will return "object". That's not very helpful. Is there some way to check if s1 is of type SomeObject ?

5 Answers 5

93

Yes, using instanceof (MDN link | spec link):

if (s1 instanceof SomeObject) { ... }
Sign up to request clarification or add additional context in comments.

3 Comments

Indeed, it goes back to the earliest JavaScript version in Netscape 2.0. (Another reason not to link to ECMA-262 is that it's staggeringly unclear and unreadable, even by standards-document standards!)
@bobince: It does take some getting used to the style. :-)
@bobince: Looking at the ES6 spec...well...let's just say I'm now actively pining for the glory days of clarity in the ES5 spec. :-)
22

Whatever you do, avoid obj.constructor.name or any string version of the constructor. That works great until you uglify/minify your code, then it all breaks since the constructor gets renamed to something obscure (ex: 'n') and your code will still do this and never match:

// Note: when uglified, the constructor may be renamed to 'n' (or whatever),
// which breaks this code since the strings are left alone.
if (obj.constructor.name === 'SomeObject') {}

Note:

// Even if uglified/minified, this will work since SomeObject will
// universally be changed to something like 'n'.
if (obj instanceof SomeObject) {}

(BTW, I need higher reputation to comment on the other worthy answers here)

1 Comment

See this link. The constructor property is another interesting way to go. Just continue to avoid the string approaches.
4

Idea stolen from http://phpjs.org/functions/get_class/, posted by SeanJA. Ripped down to work with objects only and without need for a regular expression:

function GetInstanceType(obj)
{
    var str = obj.constructor.toString();
    return str.substring(9, str.indexOf("("));
}

function Foo() {
    this.abc = 123;
}

// will print "Foo"
GetInstanceType(new Foo());

I just learned an easier way to extract the function name from the constructor:

obj.constructor.name

2 Comments

Fails with uglifiers
@s3c What fails? If you use uglifiers/tersers, usually what fails is hardcoded "name comparisons", because an uglifier/terser is shortening all names and the string comparisons fail. In that case, compare with the actual class.
2

You could also take a look at the way that they do it in php.js:

http://phpjs.org/functions/get_class:409

1 Comment

Although a link can be useful, it would have been better if the information sere included in the answer.
1

While instanceof is a correct answer it sure is ugly syntax. I offer that if you are creating custom objects you can add your own property for type and check against that like so...

var Car = function(){
    this.type = Object.defineProperty(this, "type", {value:"Car"});
}

This would create an immutable property called type that lives with the object. If you were using the Class syntax you could make it static as well.

... somewhere later ...

function addCar(car){
    if (car.type != "Car"){
        throw Error("invalid type for car");
    }

...

I think this solution is easy to implement, more intuitive, and thus easier for others to use and maintain.

Comments

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.