How do I loop through or enumerate a JavaScript object?

2,507,360

Solution 1

You can use the for-in loop as shown by others. However, you also have to make sure that the key you get is an actual property of an object, and doesn't come from the prototype.

Here is the snippet:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

For-of with Object.keys() alternative:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

Notice the use of for-of instead of for-in, if not used it will return undefined on named properties, and Object.keys() ensures the use of only the object's own properties without the whole prototype-chain properties

Using the new Object.entries() method:

Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}

Solution 2

Under ECMAScript 5, you can combine Object.keys() and Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAScript 6 adds for...of:

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8 adds Object.entries() which avoids having to look up each value in the original object:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

You can combine for...of, destructuring, and Object.entries:

for (const [key, value] of Object.entries(obj)) {
    console.log(key, value);
}

Both Object.keys() and Object.entries() iterate properties in the same order as a for...in loop but ignore the prototype chain. Only the object's own enumerable properties are iterated.

Solution 3

You have to use the for-in loop

But be very careful when using this kind of loop, because this will loop all the properties along the prototype chain.

Therefore, when using for-in loops, always make use of the hasOwnProperty method to determine if the current property in iteration is really a property of the object you're checking on:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}

Solution 4

The question won't be complete if we don't mention about alternative methods for looping through objects.

Nowadays many well known JavaScript libraries provide their own methods for iterating over collections, i.e. over arrays, objects, and array-like objects. These methods are convenient to use and are entirely compatible with any browser.

  1. If you work with jQuery, you may use jQuery.each() method. It can be used to seamlessly iterate over both objects and arrays:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. In Underscore.js you can find method _.each(), which iterates over a list of elements, yielding each in turn to a supplied function (pay attention to the order of arguments in iteratee function!):

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash provides several methods for iterating over object properties. Basic _.forEach() (or it's alias _.each()) is useful for looping through both objects and arrays, however (!) objects with length property are treated like arrays, and to avoid this behavior it is suggested to use _.forIn() and _.forOwn() methods (these also have value argument coming first):

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() iterates over own and inherited enumerable properties of an object, while _.forOwn() iterates only over own properties of an object (basically checking against hasOwnProperty function). For simple objects and object literals any of these methods will work fine.

Generally all described methods have the same behaviour with any supplied objects. Besides using native for..in loop will usually be faster than any abstraction, such as jQuery.each(), these methods are considerably easier to use, require less coding and provide better error handling.

Solution 5

Preface:

  • Object properties can be own (the property is on the object itself) or inherited (not on the object itself, on one of its prototypes).
  • Object properties can be enumerable or non-enumerable. Non-enumerable properties are left out of lots of property enumerations/arrays.
  • Property names can be strings or Symbols. Properties whose names are Symbols are left out of lots of property enumerations/arrays.

Here in 2018, your options for looping through an object's properties are (some examples follow the list):

  1. for-in [MDN, spec] — A loop structure that loops through the names of an object's enumerable properties, including inherited ones, whose names are strings
  2. Object.keys [MDN, spec] — A function providing an array of the names of an object's own, enumerable properties whose names are strings.
  3. Object.values [MDN, spec] — A function providing an array of the values of an object's own, enumerable properties.
  4. Object.entries [MDN, spec] — A function providing an array of the names and values of an object's own, enumerable properties (each entry in the array is a [name, value] array).
  5. Object.getOwnPropertyNames [MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones) whose names are strings.
  6. Object.getOwnPropertySymbols [MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones) whose names are Symbols.
  7. Reflect.ownKeys [MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones), whether those names are strings or Symbols.
  8. If you want all of an object's properties, including non-enumerable inherited ones, you need to use a loop and Object.getPrototypeOf [MDN, spec] and use Object.getOwnPropertyNames, Object.getOwnPropertySymbols, or Reflect.ownKeys on each object in the prototype chain (example at the bottom of this answer).

With all of them except for-in, you'd use some kind of looping construct on the array (for, for-of, forEach, etc.).

Examples:

for-in:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name in o) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.keys (with a for-of loop, but you can use any looping construct):

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.keys(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.values:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const value of Object.values(o)) {
    console.log(`${value}`);
}

Object.entries:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const [name, value] of Object.entries(o)) {
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertyNames:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertyNames(o)) {
    const value = o[name];
    console.log(`${name} = ${value}`);
}

Object.getOwnPropertySymbols:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertySymbols(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

Reflect.ownKeys:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Reflect.ownKeys(o)) {
    const value = o[name];
    console.log(`${String(name)} = ${value}`);
}

All properties, including inherited non-enumerable ones:

// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (let depth = 0, current = o; current; ++depth, current = Object.getPrototypeOf(current)) {
    for (const name of Reflect.ownKeys(current)) {
        const value = o[name];
        console.log(`[${depth}] ${String(name)} = ${String(value)}`);
    }
}
.as-console-wrapper {
  max-height: 100% !important;
}
Share:
2,507,360
Tanmoy
Author by

Tanmoy

I am a Web Developer currently working in USA. I currently work with C#, Azure, Web Technologies like Html and JavaScript and Microsoft Azure. Earlier I also worked on WPF, Silverlight, XML based content management system and SQL. As a hobby, I love programming, playing guitar, cooking and hiking.

Updated on July 08, 2022

Comments

  • Tanmoy
    Tanmoy almost 2 years

    I have a JavaScript object like the following:

    var p = {
        "p1": "value1",
        "p2": "value2",
        "p3": "value3"
    };
    

    How do I loop through all of p's elements (p1, p2, p3...) and get their keys and values?

  • Bryan
    Bryan over 15 years
    When using a for loop like that, key will just take on an index value, so that will just alert 0, 1, 2, etc... You need to access p[key].
  • SystemicPlural
    SystemicPlural about 13 years
    This is better than levik's solution because it allows the main logic to be only one nested loop in rather than two; making for easier to read code. Although I'd loose the the brackets around the continue; they are superfluous.
  • pimvdb
    pimvdb almost 13 years
    I would not remove the { } personally because an if without them makes it a little unclear what is part of the if and what is not. But I guess that's just a matter of opinion :)
  • Andreas Grech
    Andreas Grech almost 13 years
    Yes, I prefer keeping the { } mainly to avoid confusion if one later on needs to add something to the if scope.
  • Andreas Grech
    Andreas Grech over 12 years
    Reading my previous comment, I realized that I didn't use the correct terms, because I said "if scope"; but keep in mind that JavaScript only has function scope. So what I actually meant was "if block".
  • G-Wiz
    G-Wiz over 12 years
    Whether the JSON object is clean or not is irrelevant. If at any other time some code sets a property on Object.prototype, then it will be enumerated by for..in. If you are sure you are not using any libraries that do that, then you don't need to call hasOwnProperty.
  • user2245201
    user2245201 over 12 years
    In javascript, every object has a bunch of built-in key-value pairs that have meta-information. When you loop through all the key-value pairs for an object you're looping through them too. hasOwnPropery() filters these out.
  • Ravi Ram
    Ravi Ram about 11 years
    To get to the value: $.each(obj, function (key, value) { console.log(value.title); });
  • eomeroff
    eomeroff about 11 years
    "Unfortunately, hasOwnProperty is a method, not an operator, so in any object it could be replaced with a different function or even a value that is not a function"
  • Pencroff
    Pencroff over 10 years
    It is the slowest method of array iteration in JavaScript. You can check this on your computer - Best way to iterate over Arrays in JavaScript
  • Sk8erPeter
    Sk8erPeter over 10 years
    @Pencroff: the problem is that the question is not about looping through arrays... ;)
  • Ben Y
    Ben Y over 10 years
    Actually, For...in is not deprecated. For each...in is. But I really like the term archaeologists...I'm going to have to start using that.
  • Jamie Hutber
    Jamie Hutber over 10 years
    Indeed, I just wanted to post this method. But you beat me to it :(
  • David Harkness
    David Harkness about 10 years
    Why didn't the standard provide Object.forEach(obj, function (value, key) {...})? :( Certainly obj.forEach(function...) would be shorter and complement Array.prototype.forEach, but that would risk having objects define their own forEach property. I suppose Object.keys guards against the callback modifying the object's keys.
  • David Harkness
    David Harkness about 10 years
    Be careful with the prototype: obj = { print: 1, each: 2, word: 3 } produces TypeError: number is not a function. Using forEach to match the similar Array function may reduce the risk somewhat.
  • Sebastian
    Sebastian almost 10 years
    No! He wrote "Now I want to loop through all p elements" so he realy need a loop like in his accepted answer.
  • Sebastian
    Sebastian almost 10 years
    This is something I don't understand on stackoverflow. Richard gave the correct answer, and he was the first one giving that answer, but he did not get any +1? @Bryan var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); } is popping "p1" and "p2" in alerts, so whats wrong about that???
  • Richard Levasseur
    Richard Levasseur almost 10 years
    I think the main difference is the quality: the other answers not only tell how, but also tell the caveats (e.g., the prototype) and how to deal with those caveats. IMHO, those other answers are better than mine :).
  • Pierce
    Pierce over 8 years
    This is fantastic, thank you for posting this answer. I needed to introspect an Error object and couldn't get at the properties in a loop or a _.forIn(err) call. Using Object.getOwnPropertyNames(err) allowed me to access all the parts of the Error that I couldn't get at before. Thanks!
  • Ruan Mendes
    Ruan Mendes about 8 years
    It can be completely clean if created with Object.create(null)
  • Vatsal
    Vatsal about 8 years
    This is repeated and not even entirely correct. You need to have a check of hasOwnProperty to make this work properly
  • Evan Carroll
    Evan Carroll about 8 years
    Not just does it not help, it's not accurate. For...of only works if elements defines an iterator. That's true of Arrays, Sets, and Maps, but not of Objects.
  • abalter
    abalter about 8 years
    Could you provide a fiddle of this working? Here is my attempt. jsfiddle.net/abalter/sceeb211
  • Nicolas Bouvrette
    Nicolas Bouvrette about 8 years
    @abalter Sorry I realised I had a typo in my code. I fixed it and updated your JsFiddle here: jsfiddle.net/sceeb211/2
  • abalter
    abalter about 8 years
    I'm in chrome and getting Uncaught TypeError: Object.entries is not a function. Is it not implemented in chrome yet?
  • Nicolas Bouvrette
    Nicolas Bouvrette about 8 years
    @abalter It is. Make sure you have Chrome version 51 and that you have enabled the flag as explained in my edit and Jsfiddle comments. You can check the details here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • abalter
    abalter about 8 years
    Sorry I missed that about the flag. I see it's not a fully implemented feature yet.
  • Nicolas Bouvrette
    Nicolas Bouvrette about 8 years
    @abalter It's very early to adopt it. I'm not sure what you are trying to do but did you look at alternative solutions such as github.com/nbouvrette/forEach
  • abalter
    abalter about 8 years
    I just usually use $.each or forEach along with hasOwnProperty.
  • Hashbrown
    Hashbrown about 8 years
  • Hashbrown
    Hashbrown about 8 years
    if you don't feel like letting go of the {} notation, you can still use of without creating Maps
  • Tjorriemorrie
    Tjorriemorrie almost 8 years
    Should mention this is also appropriate if using Babel.
  • Hashbrown
    Hashbrown almost 8 years
    Case in point. So long as people scroll down and find it helpful, that's all that matters. Usually it's me trying to do something, not liking the stuff I see online, end up figuring it out, then I come back to share. It's good doco, I've actually come across my own answers before googling things I completely forgot about!
  • Pika
    Pika almost 8 years
    I found the code will generate the values but without keys. Is it possible to iterate the values with keys?
  • Artyom Pranovich
    Artyom Pranovich almost 8 years
    Yes, you can. Just return "yield [key, obj[key]];" from your generator function and then use it like the following "for(let [ key, value ] of {}) { }"
  • Janus Troelsen
    Janus Troelsen almost 8 years
    @HelpMeStackOverflowMyOnlyHope Personally I do not like modifying the prototypes of objects I did not define myself.
  • Hashbrown
    Hashbrown almost 8 years
    @JanusTroelsen did you even read the whole answer? For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
  • Moritz
    Moritz over 7 years
    Modifying the prototypes of built in objects (like Object) is generally considered an anti pattern because it can easily cause conflicts with other code. So wound not recommend doing it this way.
  • ppasler
    ppasler almost 7 years
    Just funny how underscore and jquery changed parameters :)
  • Dean Radcliffe
    Dean Radcliffe almost 7 years
    This looks totally superfluous/unneeded to me. Would you add it to every object in your system? I thought the point of providing an iterator was so that you could do `for( const [k, v] of myObject )'. It just looks like extra code providing little additional value.
  • Rolf
    Rolf over 6 years
    This is pretty cool, however for large objects, the for method might be more performant.
  • noɥʇʎԀʎzɐɹƆ
    noɥʇʎԀʎzɐɹƆ about 6 years
    Note that this technique doesn't work on plain objects, but useful nonetheless.
  • Hashbrown
    Hashbrown about 6 years
    it does work for plain objects, that's literally the whole point (as well as the variable names like ordinaryObject for emphasis that the magic still works for those types). Did you check the demos; what isn't working for you, @noɥʇʎԀʎzɐɹƆ? (P.S. your SE profile image is boss)
  • noɥʇʎԀʎzɐɹƆ
    noɥʇʎԀʎzɐɹƆ about 6 years
    My fault, I didn't read the part on the shim. It doesn't work for plain objects without modifying the prototype.
  • Hashbrown
    Hashbrown about 6 years
    Again, @noɥʇʎԀʎzɐɹƆ, not true: DEMO. Take a look at my response to @Janus. Hmm, two people have struggled and said this now, so I'll update the answer to make it better, I mightn't have explained how to adapt the technique to not need a prototype manipulation properly
  • Sean Lindo
    Sean Lindo almost 6 years
    The answers asks for a solution that returns both keys and values.
  • Eaten by a Grue
    Eaten by a Grue over 5 years
    I initially downvoted this based on the above comment until i realized that this answer came first, therefore is not "repeated". It is possibly incomplete but works just fine for many cases.
  • Marek Bernád
    Marek Bernád over 5 years
    json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"‌​value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
  • nrb
    nrb over 5 years
    please don't remove the snippet if you edit my entry
  • serraosays
    serraosays about 5 years
    Nice addition of enumerable/non-enumberable object properties.
  • ooo
    ooo about 5 years
    A custom object iterator calls the built-in array iterator of an array that generated by Object.keys() and allocated in memory... Cool!
  • Barkermn01
    Barkermn01 about 5 years
    I don't know why it was downvoted, but looking at this now this is perfect because in javascript "methods" are just properties on an Object in JS let test = function(){ this.method = () => {}; } console.log(new test());
  • Swap-IOS-Android
    Swap-IOS-Android almost 5 years
    You saved my time, Thank you
  • Onera
    Onera almost 5 years
    Happy to know:)
  • Kamil Kiełczewski
    Kamil Kiełczewski over 4 years
    to increase performance use var e=Object.entries(p) and change Object.entries(p) to e everywhere
  • Mob_Abominator
    Mob_Abominator almost 4 years
    I was exactly looking for this as I'm working with React and how for loops don't work inside <Fragment>, this is the perfect solution. Thanks a lot
  • AmerllicA
    AmerllicA almost 4 years
    Dear @Mob_Abominator, thanks for your sweet comment, I'm glad to hear it is useful for you. but I don't understand how for loops don't work inside <Fragment>. Does it still remain any problem? if it does please leave a question and tell me, I will answer. if nothing remains and you are ok now. please leave upvote to this post of me. thanks.
  • Harsh Phoujdar
    Harsh Phoujdar almost 4 years
    Works as a stand-alone, but does not work if this function returns a value for each for condition
  • ERROR 401
    ERROR 401 over 2 years
    How can I add the values that was looped? Thanks
  • mercury
    mercury over 2 years
    (for..in) for objects, (for.. of) for arrays
  • Ariful Islam
    Ariful Islam over 2 years
    Thanks for simple answer. Its saved my time.
  • Maximilian Peters
    Maximilian Peters over 2 years
    Hi, Welcome to Stackoverflow! As explained in the tour, this site is a repository of useful questions and their answers. Your answer is not essentially different from the other answers and not very useful since it does not add any new value or information. Please avoid writing duplicate answers, either edit your answer to add value or delete it altogether, this will ensure all questions and answers on the site remain useful not scattered/duplicated.
  • Irvan Hilmi
    Irvan Hilmi about 2 years
    is it possible to even do this using while loops? like while(let x in objectA || objectA[x].hasOwnProperty("childPointer")
  • Nivethan
    Nivethan about 2 years
    good answer and it's more readable than the above solutions but can you explain what happens on the .map(([key, value]) in your answer?
  • Akhil Ramani
    Akhil Ramani about 2 years
    @Nivethan the output of Object.entries will be an Array of Arrays. i.e [ ['key1', 'value'], ['key2', 'value'] ] So, map will loop over outer array with each array elements passing into its callback function one by one. So, here I have used Array de-structuring syntax ([key, value]) => {} instead of (element) => {}, where element is an array.
  • Timo
    Timo about 2 years
    I rember the diff between of and in in for loops with: Better to use of,but more practical is in because of no need for Object.entries(). Is hasOwnProperty also recommended in for..of?