This page provides examples of what appears to be an obscure bug or error in the JavaScript implementation of some browsers. It presumes you are familiar with such programming terminology as "arrays" and that you have an introductory understanding of JavaScript objects and how to reference them (and what that even means...). If, after reading this and examining the code you think you know of a workaround to the problem described below, please send it to me so that I can post it here. I also plan on using the workaround in a related project: Window Meta-object.
Bottom Line: following extensive testing (for me, at least), the implementation in IE for Windows is inconsistent and, from a developers point of view, a real pain in the ass. However, the implementation in Mozilla isn't much better. IE for Macintosh, however, passed all the tests.
Skip description and go right to the tests and results.
JavaScript allows developers to iterate through an object's properties as if the object were an array, using standard array syntax: arrayName[elementNumber] or arrayName['propertyName']. Essentially, using a type of for loop, developers can inspect every property of an object. Some documented examples of this technique in JavaScript are available here and here (scroll down about half way).
In developing the Window Meta-object, specifically, while trying to write some code that would produce a list of all properties and methods for debugging purposes, I ran across an instance in which some browsers appear to be unable to do this without causing an error.
At the time of this writing (prior to completing the tests shown below), Internet Explorer versions 5.5 and 6.0 on Windows NT 4, 2000 and 98 exhibit this apparently erroneous behavior. Additionally, some builds of Mozilla also have a problem with this, but I think versions beyond 1.0 handle it properly, regardless of the platform.
What makes this apparently incomplete implementation of JavaScript so annoying (so much so I felt compelled to document this problem for the world to see) is that there doesn't appear to be any way to trap for this error, except, of course, using the try-catch structure that is only supported in one or two browser versions that I'm aware of. In other words, there does not appear to be any way to say: "if this property is erroneous, skip it altogether and move on to the next one". This is really important because if this does turn out to be a legitimate bug or an incomplete implementation and a fix is released, there will still be possibly hundreds of millions of users out there whose browsers may have problems with your site should you choose to use the Window Meta-object or should you decide to try and parse the window properties as shown below.
This page contains JavaScript code that demonstrates where and under what conditions this error occurs. I have scoured the internet looking for information on this problem and have been unable to find any references to it. In the typical scenario, the bug manifests itself as an error message whose text is: "No such interface supported." At first blush, this might appear to be the rebirth of the IE 4.0 bug from days gone by. There are many, many, many, many references to this bug and the fix for it, but applying the fix doesn't appear to fix the problem I will demonstrate here.
In general, the goal of the test is to open a new window and set the contents of the new window to a list of the new window's properties. Here is the control window. The control window doesn't use JavaScript nor are the values displayed real. It simply demonstrates what is supposed to happen when the JavaScript code executes in the test.
The display of the data produced by the test has been simplified in order to eliminate as many variables as possible from these tests. For example, many browsers have problems rendering tables via document.write(). For this reason, the data is displayed without using tables or any other fancy code. Additionally, IE on Windows can fail opening new windows and writing to them using document.write() because it starts the write() method before the window has finished opening. The workaround, as implemented in these scripts is to use setTimeout() to give IE a chance to finish opening the window prior to writing the data. Hats off to the JavaScript God Danny Goodman.
There are actually six tests. The first test iterates through the properties of this window and prints them to a new window using self as the reference to this window. The second and third tests do the same thing, but rather than trying to get the properties of this window, they try to get the properties of the new window.
Through my own testing, I've discovered that IE for Windows is not choking on the for ( var i in object ) line, but rather on the line that tries to reference the value of i via standard array syntax: object['i'] which appears inside the for loop. Therefore, in order to demonstrate the error, the second test uses this array syntax. (Note: the code omits the single quote characters shown above. I don't think this is a problem as the single quotes are NOT omitted in Test Six and it still causes an error.)
While trouble shooting this error, I discovered that there may be workaround. Rather than trying to access the property values via the array syntax, I decided to try building a reference to the property using standard object dot notation as in window.propertyName. The construct to accomplish this is: eval("myWin."+i) and it appears inside the for loop as well.
The fourth test attempts to limit the properties inspected to values of type "string". Since I'm not particularly familiar with this method-like-thing, I'm not even sure I'm using it right, but it did appear to make a little difference. In this test, IE for Windows is actually able to make it through the first iteration before erroring out. BTW, in addition to printing the results to the new window, test four also displays an alert on each property showing the property's value. That was the only way to prove that it actually makes it through at least one iteration.
[Updated 7/30/02 3:15 PM] I've added two additional tests. Given the success with accessing the window object's properties via the self reference in Test One, I decided to try something similar in Test Five (myWin.self.propertyNameexpecting it would fail, and it did).
After posting a link to this page to microsoft.public.scripting.jscript and getting some feedback, it became apparent that some people didn't believe me, so I added an additional test: Test Six. Test Six attempts to extract the properties of the selected window object's property and tries to inspect it using the selected method. The results in the table that follows the tests were produced using Test Six.
In his JavaScript Bible, 4th Edition (Hungry Minds, Inc., 2001), page 430, Danny Goodman states:
A call to the window.open() method returns a reference to the window's object if the window opens successfully. This value is vitally important if your script needs to address elements of that new window (such as when writing to its document).
To allow other functions in your script to reference the subwindow, you should assign the result of a window.open() method to a global variable. Before writing to the window the first time, test the variable to make sure that it is not a null valuethe window may have failed to open because of low memory, for instance.
Following Mr. Goodman's advice, this test script complies with this approach and constitutes the basis upon which a judgement of faulty implementation shall be rendered. View the source if you don't believe me.
So, without further delay, please take a moment to experience the joy for yourself. Choose your medicine:
Test Six
Ah... yes... Test Six, the definitive test. After working on this for so long and trying so many approaches AND after being told this wasn't a bug, I though it would be best to create a function that demonstrates that if it is not a bug, it appears to be, at the very least, an inconsistent implementation of a JavaScript feature. Test Six can be customized. Rather than having the test be predefined by me, with Test Six you can choose which window object to test, including the window object itself, and what method to use to try and test it.
| Internet Explorer | Mozilla | ||||||
| 5.0 Win | 6.0 Win | 5.2 Mac OS X |
1.0 Win | 1.0 Mac OS X |
|||
| document | Array Syntax | F | F | P | F | F | |
| Dot Notation | F | F | P | F | F | ||
| history | Array Syntax | P | P | P1 | F | F | |
| Dot Notation | P | P | P1 | F | F | ||
| location | Array Syntax | P | P | P | F | F | |
| Dot Notation | P | P | P | F | F | ||
| navigator | Array Syntax | P | F | P | p | p | |
| Dot Notation | P | P | P | p | p | ||
| opener | Array Syntax | P | P | P | P2 | P2 | |
| Dot Notation | P | P | P | P2 | P2 | ||
| screen | Array Syntax | P1 | P1 | P | P | P | |
| Dot Notation | P1 | P1 | P | P | P | ||
| self | Array Syntax | P | F | P | P | P | |
| Dot Notation | P | F | P | P | P | ||
| window (Main Window - not Test Window) |
Array Syntax | P | P | P | P | P | |
| Dot Notation | P | P | P | P | P | ||
1. Doesn't return any results, but doesn't crash the browser either nor does it produce any error messages.
2. Actually outputs the text of the functions it finds as the value of the functions.
Microsoft has an IE challenge before them, as does the Mozilla team. As far as finding a suitable workaround, setting window.onerror to a function that returns nothing will stop the error dialogs, but short of hard coding the properties for each browser/platform, I can't think of any workaround that's worth the effort. Can you?