views:

113

answers:

2

I would like to automatically determine all of the properties (including the hidden ones) in a given Javascript object, via a generalization of this function:

function keys(obj) {
    var ll = [];
    for(var pp in obj) {
        ll.push(pp);
    }
    return ll;
}

This works for user defined objects but fails for many builtins:

repl> keys({"a":10,"b":2});  // ["a","b"]
repl> keys(Math) // returns nothing!

Basically, I'd like to write equivalents of Python's dir() and help(), which are really useful in exploring new objects.

My understanding is that only the builtin objects have hidden properties (user code evidently can't set the "enumerable" property till HTML5), so one possibility is to simply hardcode the properties of Math, String, etc. into a dir() equivalent (using the lists such as those here). But is there a better way?

EDIT: Ok, the best answer I've seen so far is on this thread. You can't easily do this with your own JS code, but the next best thing is to use console.dir in Chrome's Developer Tools (Chrome -> View -> Developer -> Developer Tools). Run console.dir(Math) and click the triangular drill down to list all methods. That's good enough for most interactive/discovery work (you don't really need to do this at runtime).

+1  A: 

This is explained in a previous answer. Basically, the spec explicitly requires (using DontEnum) that these objects aren't enumerable.

Matthew Flaschen
Sure. I think that the console.dir answer in that thread was what I was looking for, so thanks for pointing me to it.
ramanujan
+1  A: 

ECMAScript 5th ed. defines Object.getOwnPropertyNames that returns an array of all properties of the passed in object, including the ones that are non-enumerable. Only Chrome has implemented this so far.

Object.getOwnPropertyNames({a: 10, b: 2});

gives ["b", "a"] (in no particular order)

Object.getOwnPropertyNames(Math);

gives ["LN10", "PI", "E", "LOG10E", "SQRT2", "LOG2E", "SQRT1_2", "LN2", "cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]

Anurag
Aha. So this is how Chrome is doing it -- I thought they had hardcoded it.
ramanujan