Exposing an Object's Contents
We've seen how to expose the names of an object's properties, but how can we see the actual contents of each property? This is a little trickier than you might think, but it's still fairly easy to do.
eval("navAppName = navigator." + part);
After this statement executes, the variable navAppName
will hold the actual contents of the navigator.appName
property. We can then use this variable just as we would any other. (Note that some versions of Netscape Navigator will return an error if you try to declare a variable inside an eval
statement. So, it's a good idea to declare navAppName
(and assign it some dummy value] before
executing the eval
Determining a Property's Type
Here again, we can't simply use the information obtained from the action of the for/in statement. For example, if we were to alter Listing 1 to include the statement: "alert(typeof part)" in our for/in loop, each and every alert window would contain the result "string" (because the part variable contains a string). So, we need to use an eval statement once again to determine the true type of each property. Going back to Listing 1, something such as this would work nicely:
eval( "partType = typeof navigator." + part);
Once this has executed, the variable partType
will contain one of the following literals: "string
", or "undefined
". We can then use this information to determine how to best display the value in the property. (As you might have noticed, there is no "array
" type returned by the typeof
The first step in the function is to create some local variables that will hold the contents of the object and its individual properties. Second, we use an eval statement to turn the name of our object into a reference to the object itself. Then, we begin building our result table and enter the for/in loop that will expose the properties of the object.
After this is all done, it's a simple matter of determining the type of the property, and then outputting the appropriate HTML based on that type. If the property is a simple scalar value, we just print it out with an appropriate description. If the type is an object or array (and it isn't null), we include a link that will reload the page and pass this property/object to the showObjStructure function. This allows us to "drill down" into each object.
Using the Object Browser
If you don't specify an object, the self object is loaded by default.
Finally, a document.write statement is used to invoke the showObjStructure function and display the contents of the specified object.
One of the main uses for this simple object browser is to be able to dynamically view the differences between the Document Object Models of various Web browsers. While this object browser does work in both Navigator and Internet Explorer (IE), you'll notice right away that IE doesn't expose as many of its built-in objects to the for/in statement as Navigator does. For example, if you try to look at IE's navigator.plugins array, you'll get an error message. Unfortunately, there's really not much that can be done about this because IE simply doesn't let the for/in statement peek at the properties of this object. (If you want get rid of these error messages in IE, enclose the for/in loop in a try/catch block. Note that this will make the script incompatible with Navigator, which does not currently support try/catch error handling.)
Another difference between browsers is that when looking at the self or window object, Navigator exposes all programmer-defined global variables, while IE does not. Another Navigator quirk is that variables declared inside functions are exposed as if they were global, unless you use the var keyword when you declare them. To see an example of this, remove the var keyword from any of the local variables defined in the showObjStructure function and then examine the self object. (Tip: Do not remove the var keyword from the declaration for the result variable; on second thought, give it a try and see what happens!)
The only real drawback to this simple object browser is that it requires a page reload whenever you drill down to see the structure of another object. For complex objects with calculated values in them, this could have the nasty side effect of resetting them to their original state. However, this could be solved fairly easily by loading the object browser in one frame and the objects you want to examine in another.
Got a Debugging Trick of Your Own?