|Written by Ian Elliot|
|Thursday, 05 March 2015|
Page 3 of 3
The Mystery Of Instanceof - Subtype
Knowing what type an object is isn't the end of the story.
In a class based language the type hierarchy means that it is possible to consider an object as being of a number of different types and sub-types.
For example, every object is an instance of Object as well as what ever class it actually is.
If class B inherits from class A then an instance of class B can be considered to be a class A instance as well as it has all of the properties and methods of an instance of class A.
For example if an object d has a prototype chain:
then it is not only an instance of D but it can also be treated as an instance of C, B or A.
With this explained we can now understand the intention of the instanceof operator.
The instanceof operator looks as if it is a way of testing to see if an object was constructed by a particular constructor but this isn't what it does at all.
It is often explained that we can test to see if obj has constructor C using:
which will return true if obj was constructed by C.
This looks as if it is just an alternative to testing an object's constructor property but this is not what it is doing.
The instanceof operator doesn't check the constructor but the prototype that the constructor specifies.
compares the object's prototype to the prototype specified in the constructor. If they are the same then it might seem reasonable to conclude that obj was constructed by C.
But things are a little more complicated than this simple introduction suggests.
Not only does instanceof test to see if the prototype the constructor specifies is the immediate prototype of the object it also checks to see if the prototype is any where in the objects complete prototype chain.
So to be 100% clear:
Instanceof doesn't test that the object was created by the constructor you specify. It tests if the object has the prototype specified by the constructor is in the object's prototype chain.
So if obj instanceof C is true you can't conclude that C was the objects constructor. All you can conclude is that object has a specific prototype object P in its prototype chain in hence it has all of the properties of P.
You could say that the statement
being true lets you conclude that obj is of type P where P is the prototype object specified by C.
For example consider the following
We have defined two different constructors A and B with the same prototype p.
That is the inheritance branches
Notice that A and B construct objects with different sets of properties - an instance of A has x and z and of D has x and y.
Now if you create an object using B
and test using instanceof
you will discover that b is an instance of A (i.e. the result is true) even though it was created by B.
You can also see that there is no reasonable sense in which b is an instance of A - it only shares the same prototype with objects created by A.
In this sense it would be more reasonable to say that obj was a p.
If you restrict yourself to a strictly non-branching inheritance structure then instanceof does sort of work.
If you change the previous example to one in which D "inherits" from C then it makes a little more sense:
You can see that now we have an inheritance with no branches given by
i.e. any object created by B has all of the properties of one created by A and both have all of the properties of p.
Now if you create an instance of B then
is true because b has p in its prototype chain and because the inheritance is hierarchical it also has all of the properties of A.
Notice also that in this case a A would not be considered to be an instance of a B because B's prototype is A and A is not in A's prototype chain.
As long as you stick to a strict hierarchical non-branching"inheritance" using prototypes then the instanceof operator gives you the results you might expect.
If the inheritance branches, as most do then you get a seemingly wrong answer from instanceof if you regard it as telling you about constructors.
Where Are We
Knowing what an object's constructor is does specify what properties it has and so it is a reasonable interpretation of type. The problem is that the constructor property, which is supplied by the prototype object, is only set automatically for the default prototype object. If you supply a prototype object of your own to build up a prototype chain then you have remember to set its constructor property to reference the constructor.
This can be made to work but it isn't ideal.
Knowing that a particular object p say is in and object's prototype chain lets you treat the object as if it was an instance of p i.e. its subtype is P.
The instanceof operator doesn't check that an object is an instance of a particular constructor i.e. was created by the constructor as its name suggests. It simply checks to see if the prototype specified by the constructor is in the object's prototype chain. Hence it checks if the object is a subtype P the same as the prototype specified by the constructor.
The problem with the instanceof operator is that it seems to be checking for one thing and it actually checks, imperfectly for another. However the basic idea that a prototype being in an object's prototype chain determines a sort of analog of subtype is a good one. This idea shouldn't be thrown out along with the broken attempt at an instanceof operator.
It is clear that with the current model of prototype inheritance the best analog of type is the constructor and the best analog of sub-type is the prototype chain.
However at the start of the chapter it was suggested that trying to find an analog of class based type might not be a good idea at all and if it is then perhaps constructor/prototype definitions are not the way to go.
In the next chapter we meet duck testing and prototype construction as alternatives to class based type.
There is a newer version of the draft of the book here.
To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, Facebook, Google+ or Linkedin, or sign up for our weekly newsletter.
or email your comment to: email@example.com
|Last Updated ( Sunday, 10 May 2015 )|