12

If I have a class:

class Haha constructor: (@lolAmount = 1) -> alert @lolAmount 

And I want to check if an object is of the right class, Is it always safe to use constructor.name:

haha = new Haha() unless haha.constructor.name is 'Haha' throw Error 'Wrong type' 

or is it better to use instanceof:

haha = new Haha() unless haha instanceof Haha throw Error 'Wrong type' 

One argument I have for instanceof is when using extends:

class BigHaha extends Haha bigHaha = new BigHaha console.log bigHaha instanceof Haha #true 

but how safe is it, being a JavaScript operator - I feel like I should be sceptical about it.

On the other hand, with constructor.name it is very clear what is happening. Is it guaranteed that constructor.name will be set on all objects?

Thanks for any info.

1 Answer 1

17

First of all, constructor is also straight JavaScript:

Returns a reference to the Object function that created the instance's prototype.

So when you say o.constructor, you're really doing straight JavaScript, the name constructor for the CoffeeScript object initialization function is a separate matter.

So now you have a choice between using JavaScript's constructor property or JavaScript's instanceof operator. The constructor just tells you what "class" was used to create the object, instanceof on the other hand:

[...] tests whether an object has in its prototype chain the prototype property of a constructor.

So instanceof is the right choice if you want to allow for subclassing.

Sign up to request clarification or add additional context in comments.

8 Comments

Great thanks! Just to confirm though, the name property on the constructor is CoffeeScript yes? And is reliable for classes where I don't care about sub/superclasses?
@phenomnomnominal: The name comes from JavaScript's Function and is non-standard so it may or may not work. Use instanceof or compare the constructor function directly. But really, just use instanceof.
I recall a discussion in the coffeescript issues about the constructor.name property being mangled by closure/uglifyjs. Another good thing to know is that instanceof is only really safe to use for your own objects, and not the built-in types. But I agree, for this use, instanceof is the better choice. Edit: here is a similar discussion.
@LinusGThiel: I could see running into name problems in all sorts of ways, especially if you're mixing JS and CS (M = Backbone.Model.extend({}), for example, is anonymous). And yes, all bets are off with native types.
I've been using underscore.js for native type-checking - would you consider instanceof for my own classes and _.isWhatever for native objects to be fairly robust?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.