I'm writing a Javascript stacktrace library. The library needs to detect wether a particular object or function was created by the programmer or was there as part of the environment (including built-in objects). Host objects are becoming a bit problematic due to their unpredictable behaviour, so I'm after an environment-agnostic way to determine if a particular object in Javascript is a host object (see ECMAScript 3 - 4.3.8). However, distinguishing host objects from native objects and primitive values is useful for programmers in other projects, particularly in browser-less environments, so I'd like to focus on that, rather than the problems host objects cause in my library or on distinguishing programmer-created objects.
So far I've only been able to come up with solutions that depend on the environment running javascript code. For example:
// IE Only: does not implement valueOf() in Host Objects
var isHost = (typeof obj === 'object' && typeof obj.valueOf === 'undefined');
// Firefox Only: Host objects have own constructor
var isHost = (obj.constructor && obj.hasOwnProperty('constructor'));
I noticed that jQuery's own isPlainObject() method is also dependent on environment, and that the logic is rather convoluted.
Perhaps this is because thats the nature of the beast with host objects (since their behaviour is defined by the environment), but I would like to dig a bit further to see if this is possible and was wondering if somebody has run across this particular problem before and has a solution ready.
So. Does anybody know a simple platform-independent solution to test for Host Objects? And if it runs in a browser-less environment such as Node or Rhino all the better for it.
Possible approaches (that may not work):
- Testing for characteristics of host objects seems like a lost cause, given that there is no specification for their behaviour, however testing whether the object is part of the ES3 specification may be a possibility.
- I have tried using
Object.prototype.toString()
given that its defined quite specifically, but the results are inconclusive as some environments (namely IE) choose to return the same value for native and host objects. - It may be possible to do this by checking whether the ultimate
constructor
of an object through the prototype chain really is aninstanceof Function
.