The Quiet Horror of instanceof Operator

During the last months I was busy with NativeScript more than ever. While my work keeps me busy with embedding V8 JavaScript engine I rarely have the chance to write JavaScript. Recently I had to deal with mapping Java OOP inheritance into JavaScript and more specifically I had to fix a failing JavaScript unit test which uses instanceof operator. So I grabbed the opportunity to dig more into instanceof internals.

It is virtually impossible to talk about instanceof operator without mentioning typeof operator first. According MDN documentation

The typeof operator returns a string indicating the type of the unevaluated operand.

As described typeof operator does not seem useful. Probably the most interesting thing the use of unevaluated word. This allows us to test whether particular symbol is defined. For example

if (typeof x !== 'undefined')

will execute without ReferenceError even when x is not present.

Let’s see instanceof documentation

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

After digging into instanceof operator I was even more puzzled. While typeof operator was introduced since the first edition of ECMAScript it seems that language designer(s) didn’t have clear idea about instanceof operator. It is mentioned as a reserved keyword in the second edition of ECMAScript and it is finally introduced into the third edition of ECMAScript. The operator definition is clear but I have troubles finding meaningful uses. Let’s see the following common example.

if (x instanceof Foo) {
   x.bar();
}

I feel uneasy with the assumption that if x has Foo‘s prototype somewhere in its prototype chain then it is safe to assume that bar exists. Mixing properties of nominal type system with JavaScript just doesn’t seem intuitive to me. I guess there are some practical scenarios where typeof and instanceof operators are useful but my guess is that their number is limited.

Leave a Reply

Your email address will not be published. Required fields are marked *