How to list the properties of a JavaScript object?

How to list the properties of a JavaScript object?

Say I create an object thus:
var myObject =
{“ircEvent”: “PRIVMSG”, “method”: “newURI”, “regex”: “^http://.*”};

What is the best way to retrieve a list of the property names? i.e. I would like to end up with some variable ‘keys’ such that:
keys == [“ircEvent”, “method”, “regex”]

Solutions/Answers:

Solution 1:

In modern browsers (IE9+, FF4+, Chrome5+, Opera12+, Safari5+) you can use the built in Object.keys method:

var keys = Object.keys(myObject);

The above has a full polyfill but a simplified version is:

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

Alternatively replace var getKeys with Object.prototype.keys to allow you to call .keys() on any object. Extending the prototype has some side effects and I wouldn’t recommend doing it.

Solution 2:

As slashnick pointed out, you can use the “for in” construct to iterate over an object for its attribute names. However you’ll be iterating over all attribute names in the object’s prototype chain. If you want to iterate only over the object’s own attributes, you can make use of the Object#hasOwnProperty() method. Thus having the following.

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

Solution 3:

As Sam Dutton answered, a new method for this very purpose has been introduced in ECMAScript 5th Edition. Object.keys() will do what you want and is supported in Firefox 4, Chrome 6, Safari 5 and IE 9.

You can also very easily implement the method in browsers that don’t support it. However, some of the implementations out there aren’t fully compatible with Internet Explorer. Here’s a more compatible solution:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

Note that the currently accepted answer doesn’t include a check for hasOwnProperty() and will return properties that are inherited through the prototype chain. It also doesn’t account for the famous DontEnum bug in Internet Explorer where non-enumerable properties on the prototype chain cause locally declared properties with the same name to inherit their DontEnum attribute.

Implementing Object.keys() will give you a more robust solution.

EDIT: following a recent discussion with kangax, a well-known contributor to Prototype, I implemented the workaround for the DontEnum bug based on code for his Object.forIn() function found here.

Solution 4:

Note that Object.keys and other ECMAScript 5 methods are supported by Firefox 4, Chrome 6, Safari 5, IE 9 and above.

For example:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5 compatibility table: http://kangax.github.com/es5-compat-table/

Description of new methods: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/

Solution 5:

Object.getOwnPropertyNames(obj)

This function also shows non-enumerable properties in addition to those shown by Object.keys(obj).

In JS, every property has a few properties, including a boolean enumerable.

In general, non-enumerable properties are more “internalish” and less often used, but it is insightful to look into them sometimes to see what is really going on.

Example:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

Also note how:

  • Object.getOwnPropertyNames and Object.keys don’t go up the prototype chain to find base
  • for in does

More about the prototype chain here: https://stackoverflow.com/a/23877420/895245

Solution 6:

I’m a huge fan of the dump function.

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion
alt text