722

How do I enumerate the properties of a JavaScript object?

I actually want to list all the defined variables and their values, but I've learned that defining a variable actually creates a property of the window object.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
davenpcj
  • 12,508
  • 5
  • 40
  • 37

14 Answers14

893

Simple enough:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

Now, you will not get private variables this way because they are not available.


EDIT: @bitwiseplatypus is correct that unless you use the hasOwnProperty() method, you will get properties that are inherited - however, I don't know why anyone familiar with object-oriented programming would expect anything less! Typically, someone that brings this up has been subjected to Douglas Crockford's warnings about this, which still confuse me a bit. Again, inheritance is a normal part of OO languages and is therefore part of JavaScript, notwithstanding it being prototypical.

Now, that said, hasOwnProperty() is useful for filtering, but we don't need to sound a warning as if there is something dangerous in getting inherited properties.

EDIT 2: @bitwiseplatypus brings up the situation that would occur should someone add properties/methods to your objects at a point in time later than when you originally wrote your objects (via its prototype) - while it is true that this might cause unexpected behavior, I personally don't see that as my problem entirely. Just a matter of opinion. Besides, what if I design things in such a way that I use prototypes during the construction of my objects and yet have code that iterates over the properties of the object and I want all inherited properties? I wouldn't use hasOwnProperty(). Then, let's say, someone adds new properties later. Is that my fault if things behave badly at that point? I don't think so. I think this is why jQuery, as an example, has specified ways of extending how it works (via jQuery.extend and jQuery.fn.extend).

Community
  • 1
  • 1
Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
  • 7
    I think @bitwiseplatypus is just saying "be careful". It's my opinion that JavaScript's for/in should only be taught accompanied by a mention of hasOwnProperty() and other less-than-obvious edge-cases of prototypal inheritance. – pcorcoran Sep 18 '08 at 04:41
  • Interestingly this does not work for getter properties defined with Object.defineProperty but does work for direct getters. See my [jsfiddle](http://jsfiddle.net/Sgf8N/4/). – Ciantic Oct 14 '11 at 13:50
  • 29
    I think *most* people are surprised that `for(x in {})` enumerates anything at all, since it looks like a simple dictionary key iteration. It's very unexpected and definitely merits special warning. – Glenn Maynard Apr 17 '12 at 21:19
  • 4
    I'd like to know how many times people have actually encountered a bug with this. I did, once, and it was really simple to spot. A warning when teaching JS `for in` loops is good, so you can filter inherited properties if you need to. Littering my `for loop`s with blind `hasOwnProperty` checks to cater to people who don't have a basic understanding of JS is **not** warranted. – Ruan Mendes Mar 17 '14 at 17:07
  • @GlennMaynard, it doesn't enumerate anything at all in this instance. http://jsbin.com/vupexuva/1/edit – Siddharth Aug 09 '14 at 17:14
  • Note: this won't work for some objects, such as `Error`, because the properties are non-enumerable. In such cases, you want to use `Object.getOwnPropertyNames`. – vossad01 Oct 24 '16 at 16:24
  • what about objects that have a function? The function contents is also returned ??? – MrLister Jul 10 '18 at 02:39
  • I found a case where this doesn't work: in objects of subtype MouseEvent, during "Item[Sub]". I verified that Sub is a string. The Firefox Console gives error message "NS_ERROR_NOT_IMPLEMENTED". I have no clue as to what feature is not implemented. – David Spector Dec 01 '18 at 18:21
  • This answer was originally written just over 10 years ago. Things change, and it's no surprise that approaches involving anything like this should be examined for continued accuracy. I suppose this is one of the most glaring limitations of StackOverflow - the data goes stale in many cases. :) – Jason Bunting Dec 13 '18 at 22:26
  • 1
    @DavidSpector At a guess this message refers to the fact that iterators are _not implemented_ for object properties, only for array elements. You probably omitted let/var and wrote `for (thing in set) { ... }` which is easy to do. – Peter Wone Apr 24 '20 at 02:46
235

Use a for..in loop to enumerate an object's properties, but be careful. The enumeration will return properties not just of the object being enumerated, but also from the prototypes of any parent objects.

var myObject = {foo: 'bar'};

for (var name in myObject) {
  alert(name);
}

// results in a single alert of 'foo'

Object.prototype.baz = 'quux';

for (var name in myObject) {
  alert(name);
}

// results in two alerts, one for 'foo' and one for 'baz'

To avoid including inherited properties in your enumeration, check hasOwnProperty():

for (var name in myObject) {
  if (myObject.hasOwnProperty(name)) {
    alert(name);
  }
}

Edit: I disagree with JasonBunting's statement that we don't need to worry about enumerating inherited properties. There is danger in enumerating over inherited properties that you aren't expecting, because it can change the behavior of your code.

It doesn't matter whether this problem exists in other languages; the fact is it exists, and JavaScript is particularly vulnerable since modifications to an object's prototype affects child objects even if the modification takes place after instantiation.

This is why JavaScript provides hasOwnProperty(), and this is why you should use it in order to ensure that third party code (or any other code that might modify a prototype) doesn't break yours. Apart from adding a few extra bytes of code, there is no downside to using hasOwnProperty().

Ryan Grove
  • 2,919
  • 1
  • 15
  • 11
  • 4
    Devotees of hasOwnProperty are usually those who have a) suffered from aggressive common libraries [eg.: Prototype.js circa 2003], or b) built foundations for heterogeneous systems (think: web portals). Everyone else should just wrap hasOwnProperty in an iterator pattern and go out for beer. – pcorcoran Sep 18 '08 at 04:56
  • 31
    This pattern is needed and used because javascript conflates "Actor objects" with "Hash tables". when the object is a *description of behaviors and traits*, then the usual rules apply, you want to know about the properties on the object without concern for how they got there. If, on the other hand, your using the object as a key-value store, then you are most likely only interested in the actual keys that are actually stored on the object. Other properties are coincidental and don't represent the actual state of the object. Other languages solve this distinction with distinct types. – SingleNegationElimination Jul 17 '11 at 16:14
  • for my understanding as a js newby, how does `Object.prototype.baz = 'quux';` change the `myObject` object? – JHBonarius Jul 07 '20 at 11:20
  • Try evaluating `myObject.baz` now :) Property accesses will climb up the prototype chain until a match is found or the prototype chain ends, so it'll find `baz` on `Object.prototype` and return it. Also, I realize this answer is from 2008, but I'd suggest using `Object.hasOwn(myObject, name)` now that it's available. – Ian Kim Sep 09 '22 at 18:00
52

In modern browsers (ECMAScript 5) to get all enumerable properties you can do:

Object.keys(obj) (Check the link to get a snippet for backward compatibility on older browsers)

Or to get also non-enumerable properties:

Object.getOwnPropertyNames(obj)

Check ECMAScript 5 compatibility table

Additional info: What is a enumerable attribute?

Carlos Ruana
  • 2,138
  • 1
  • 15
  • 14
  • 3
    `Object.getOwnPropertyNames(obj)` is what you want if you are dealing with some sort of Error object (ex. TypeError) because the properties are non-enumerable. – vossad01 Oct 24 '16 at 16:18
  • @vossad01 Unfortunately `getOwnPropertyNames` doesn't seem to work with `ErrorEvent` objects: it only lists `isTrusted`. However `for( var pn in errEv ) console.log( pn ); }` _does_ work. This is frustrating and inconsistent. – Dai Oct 07 '21 at 14:08
50

The standard way, which has already been proposed several times is:

for (var name in myObject) {
  alert(name);
}

However Internet Explorer 6, 7 and 8 have a bug in the JavaScript interpreter, which has the effect that some keys are not enumerated. If you run this code:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

If will alert "12" in all browsers except IE. IE will simply ignore this key. The affected key values are:

  • isPrototypeOf
  • hasOwnProperty
  • toLocaleString
  • toString
  • valueOf

To be really safe in IE you have to use something like:

for (var key in myObject) {
  alert(key);
}

var shadowedKeys = [
  "isPrototypeOf",
  "hasOwnProperty",
  "toLocaleString",
  "toString",
  "valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
  if map.hasOwnProperty(a[i])) {
    alert(a[i]);
  }
}

The good news is that EcmaScript 5 defines the Object.keys(myObject) function, which returns the keys of an object as array and some browsers (e.g. Safari 4) already implement it.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
Fabian Jakobs
  • 28,815
  • 8
  • 42
  • 39
27

I think an example of the case that has caught me by surprise is relevant:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

But to my surprise, the output is

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

Why? Another script on the page has extended the Object prototype:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};
Nhan
  • 3,595
  • 6
  • 30
  • 38
cyberhobo
  • 646
  • 7
  • 7
  • Interesting, I suppose that means it's possible to NOT call the callback when redefining the forEach function, which could make enumerating the properties break. – davenpcj Apr 21 '09 at 15:00
  • Yes, my point is that another script could have added anything to the object prototype. Those kind of changes may be there, they may not, and added methods might do anything. I don't claim this example of forEach is good - just something a script might do that would modify the results of for .. in for other scripts. – cyberhobo Apr 27 '09 at 17:22
  • In light of the modern trends in JavaScript development, modifying the prototype of any of the base types seems a bad decision to me; there are other ways to skin most of the cats that drive people to do it in the first place. – Jason Bunting Jul 21 '10 at 21:05
  • 1
    I agree, but if other code does it, I still don't want mine to break. – cyberhobo Jul 29 '10 at 01:17
  • @cyberhobo - Understood, but who caused it to break? You? No, someone that came after and didn't think things through or know what they were getting themselves into, and thus they are idiots. Any JavaScript guy worth his salt knows that modifying the prototypes of any object that wasn't originally theirs to begin with is potentially playing with fire. – Jason Bunting Nov 24 '10 at 23:23
  • It does seem like more developers are aware of this mistake. I would be happy if my example proves totally irrelevant and new developers learning how to enumerate objects don't even need to be aware of the possibility. – cyberhobo Nov 27 '10 at 17:10
  • Color me doubtful as to your surprise. – Michael Cole Mar 28 '19 at 17:23
17
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}
Andrew Hedges
  • 21,688
  • 16
  • 67
  • 79
12

Here's how to enumerate an object's properties:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chtioui Malek
  • 11,197
  • 1
  • 72
  • 69
11

Simple JavaScript code:

for(var propertyName in myObject) {
   // propertyName is what you want.
   // You can get the value like this: myObject[propertyName]
}

jQuery:

jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
EmRa228
  • 1,226
  • 13
  • 22
9

I found it... for (property in object) { // do stuff } will list all the properties, and therefore all the globally declared variables on the window object..

kapa
  • 77,694
  • 21
  • 158
  • 175
davenpcj
  • 12,508
  • 5
  • 40
  • 37
8

You can use the for of loop.

If you want an array use:

Object.keys(object1)

Ref. Object.keys()

Sam Greenhalgh
  • 5,952
  • 21
  • 37
Walle Cyril
  • 3,087
  • 4
  • 23
  • 55
7

If you are using the Underscore.js library, you can use function keys:

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dkl
  • 3,850
  • 2
  • 27
  • 26
5

Python's dict has 'keys' method, and that is really useful. I think in JavaScript we can have something this:

function keys(){
    var k = [];
    for(var p in this) {
        if(this.hasOwnProperty(p))
            k.push(p);
    }
    return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });

EDIT: But the answer of @carlos-ruana works very well. I tested Object.keys(window), and the result is what I expected.

EDIT after 5 years: it is not good idea to extend Object, because it can conflict with other libraries that may want to use keys on their objects and it will lead unpredictable behavior on your project. @carlos-ruana answer is the correct way to get keys of an object.

Fabio Montefuscolo
  • 2,258
  • 2
  • 21
  • 18
2

If you're trying to enumerate the properties in order to write new code against the object, I would recommend using a debugger like Firebug to see them visually.

Another handy technique is to use Prototype's Object.toJSON() to serialize the object to JSON, which will show you both property names and values.

var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'

http://www.prototypejs.org/api/object/tojson

Chase Seibert
  • 15,703
  • 8
  • 51
  • 58
1

I'm still a beginner in JavaScript, but I wrote a small function to recursively print all the properties of an object and its children:

getDescription(object, tabs) {
  var str = "{\n";
  for (var x in object) {
      str += Array(tabs + 2).join("\t") + x + ": ";
      if (typeof object[x] === 'object' && object[x]) {
        str += this.getDescription(object[x], tabs + 1);
      } else {
        str += object[x];
      }
      str += "\n";
  }
  str += Array(tabs + 1).join("\t") + "}";
  return str;
}
Nhan
  • 3,595
  • 6
  • 30
  • 38
Felix Lapalme
  • 1,058
  • 1
  • 11
  • 25