« Getting sex in JavaScript | Main | Cease & Desist, but not really »

The inconsistent instanceof operator

Last year I helped an ex-colleague of mine debug a problem with identifiying objects passed to a function in an iframe using the instanceof operator. The problem was that Microsoft Internet Explorer didn't give the expected results and we had to code our way around it. I've been wondering ever since about when theory and practice coincide, and so I created a testcase and tested whether the instanceof operator works as it should.
First a quick theory brush up: When you've got an object and want to find out what class it was created from you use the instanceof operator. One way to do it can be like this:
if(myVariable instanceof myClass) { ... }
The test should be true when myVariable is an instance (object) of the class myClass. To create an object (an instance) from a class you use the new operator, e.g: myVariable = new myClass(); The idea behind the instanceof operator is that it provides the possibility to test which class an object originated from, and thereby use only methods and properties you know exist in instances of that class. In other words, you can write a method that does different things depending upon which class it belongs to, which in turn can result in more powerful code that's still easy to maintain. This is a really good idea, but it's not consistently implemented. As I found out earlier MSIE(Microsoft Internet Explorer) is unable to test objects sent as arguments from another window. The question I sought answered was whether there existed other cases where the tests failed, and if so, which browsers were affected. I created a testcase that consists of the original problem case (#1) and two variations. The first test calls a function in a (different) window passing a local variable as the argument. As I mentioned earlier this is where MSIE(Microsoft Internet Explorer) fails when the function is in another window. In the test the function is called twice, first a primitive number value (var notNumberClass = 8;) is passed and the test should tell it's not an instance of any of the basic classes. The second time an object created from the Number class is passed (var isNumberClass = new Number(8);) and it should be identified as being an instance of the Number and Object classes (remember that all classes in JavaScript are descendants of the Object class). The first variation (case #2) tries to turn the problem around by calling a function local to the testcase window/frame while the argument moves around. Again the test is done with both a primitive number value and an instance of the Number class, and the results should be the same as in the first case. I created this second test because I wasn't sure whether the browsers that didn't correctly tackle case #1 would show the same symptoms in the second case. According to my test results the browsers seem to fail in the exact same way in both cases. The last case (#3) moves both the function and the argument around, but the variable being tested is always local to the window containing the function. None of the browsers I tested had any problems with this test. I ran the tests with four browsers: * Microsoft Internet Explorer 6 * Mozilla 1.5 * Opera 7.23 * Konqueror 3.1-15 Red Hat Mozilla 1.5 is the only browser that doesn't fail on any of the three tests. The other three browsers all get test #3 right, but denies that the object is an instance of the classes Number and Object in test #1 and #2. I've yet to read enough of the ECMA-262 spec to understand why they behave like they do, but as far as I understand the definition of the instanceof operator it's rather surprising that that it shouldn't work across windows/frames. [Note: This is an English translation of an article I wrote for my Norwegian blog. If you'd prefer the Norwegian version, visit Instanser av klasser, instanceof-operatoren]

About

This page contains a single entry from the blog posted on January 11, 2004 4:41 PM.

The previous post in this blog was Getting sex in JavaScript.

The next post in this blog is Cease & Desist, but not really.

Many more can be found on the main index page or by looking through the archives.