Function#toString
Most Javascript implementations will return the source code of a function if you call the function instance's toString
method:
function foo() {
return a;
}
alert(foo.toString()); // Alerts "function foo() { return a; }"
This is non-standard behavior, but widely-supported; you may find it quite useful for reverse-engineering. Calling it on the Spot.Ui.LiveWidget
function may be interesting, as well as on functions bound to the properties of the object it returns. Which brings us to...
Edit Of course, if unobfuscated source is available (shout out to Sean), you don't need this...
Looping through Properties: for..in
If it's really a Javascript object, you can do this to find out what properties it has:
var name, own;
for (name in obj) {
own = obj.hasOwnProperty(name);
alert(name + " (" + (own ? "own" : "inherited") + ")");
}
That will tell you the names of its (enumerable) properties and whether those are properties of the instance itself, or its prototype object.
for..in
Example
function Thingy() {
}
Thingy.prototype.alpha = "a";
var t = new Thingy();
t.beta = "2";
The loop above would show:
alpha (inherited)
beta (own)
(In no particular order.)
Further Information
Enumerable vs. Non-Enumerable properties
Note that not all properties are "enumerable". For instance, all (or nearly all) of the properties specified by the spec on objects like Array
, String
, etc. are non-enumerable. But until recently that was just something that could be done by the Javascript implementation itself; there was no mechanism for marking your own properties as being non-enumerable. The new 5th edition spec provides a means of doing that, but it isn't widely supported or used (yet).
Non-Existant Properties
The object you're querying may change its behavior based on whether a property is present or not; in that situation, you'd have no way of knowing, since a non-existant property doesn't show up in the for..in
loop (unlike a property that exists but has an undefined
value, which does). E.g.:
function doSomething(options) {
if (options.foo) {
// There's a `foo` and it has a value; do something with it
}
The foo
property may not exist at all on options
, so this reverse-engineering wouldn't reveal that the code did something with it.
Warning
Do not try the for..in
loop above on host objects, such as DOM nodes. It may work in some implementations, but usually not, and in some cases (IE6) it'll crash the browser. It's totally safe for Javascript objects, though.