JavaScript (and Backbone) Inheritance
How do you determine whether an object is an instance of a class in JavaScript?
The appropriately named instanceof
operator is your best friend.
Per the MDN entry:
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
With that in mind let's run down some of the common use cases for instanceof using the native Date class:
var date = new Date();
date instanceof Date; // true
date instanceof Object; //true
Since instanceof
checks the whole prototype chain, date instanceof Object
also evaluates to true
.
By a quirk in a language full of quirks instanceof
won't apply to literals. For
example:
var literal = 'I am a string literal',
instantiated = new String( 'I am also a string' );
literal instanceof String; // false
literal instanceof Object; // false
instantiated instanceof String; // true
instantiated instanceof Object; // true
Inheritance for Instantiated User-Defined Classes
Onto a more complex example. What about custom classes that extend
Backbone objects? Backbone uses
the extend
method to create child classes, but the instantiated objects
still work with the instanceof
operator.
var TestModel = Backbone.Model.extend( {} ),
TestCollection = Backbone.Collection.extend( {} ),
TestView = Backbone.View.extend( {} ),
myModel = new TestModel(),
myCollection = new TestCollection();
myModel instanceof TestModel; // true
myModel instanceof Backbone.Model; // true
myCollection instanceof TestCollection; // true
myCollection instanceof Backbone.Collection; // true
Checking Inheritance for Class Definitions
But what if you want to see if a class inherits from another without having to instantiate an object? Classes in JavaScript are more of a hack, and not well supported with utility functions. Determining inheritance between two uninstantiated classes is a bit trickier, but possible.
var TestModel = Backbone.Model.extend( {} );
TestModel instanceof Backbone.Model; // false
TestModel.prototype instanceof Backbone.Model; // true
Alternatively Javscript provides an isPrototypeOf
method
which can also be cajoled into determining inheritance for
uninstantiated classes:
var TestModel = Backbone.Model.extend( {} );
Backbone.Model.prototype.isPrototypeOf( TestModel ); // false
Backobne.Model.prototype.isPrototypeOf( TestModel.prototype ); // true