2340

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(propt + ': ' + obj[propt]);
}

How does the variable propt represent the properties of the object? It's not a built-in method or property. Why does it come up with every property in the object?

lolbas
  • 794
  • 1
  • 9
  • 34
Rafay
  • 23,785
  • 4
  • 20
  • 27
  • 14
    `if (typeof(obj[propt]) === 'object') {`/* Do it again */ `}` – noob Nov 29 '11 at 14:39
  • 13
    Well, really sorry for this question. I know what a loop is, I couldn't get my head around "looping through object properties", which I think is cleared now. Also, they have recommended me "JavaScript Step by Step 2nd Edition - Steve Suehring at school. – Rafay Nov 29 '11 at 14:39
  • 276
    This is a fine begginers question. I'd add that I have 15 years of professional experience with other languages and I needed this answer. I'd plus 2000 if I could. – Nathan C. Tresch Feb 01 '13 at 13:28
  • 1
    @ItayMoav-Malimovka From parsing the language in the question, as a linguist it's clear that sees that it's looping, he wants to know that the IN operator passes the object properties as "propt". – Nathan C. Tresch Feb 01 '13 at 13:30
  • 2
    possible duplicate of [How do I enumerate the properties of a javascript object?](http://stackoverflow.com/questions/85992/how-do-i-enumerate-the-properties-of-a-javascript-object) – Георги Кременлиев Jul 26 '13 at 15:27
  • 74
    Crazy, but I've been coming to this page every few months for years to relearn the syntax on how to do this. I don't bother to remember how to do this... I just remember that this page is always here on SO. – Dave Jul 09 '15 at 15:29
  • this answer shows two alternatives using underscore and lodash. Helpful if they are already available to you: http://stackoverflow.com/a/19023387/1483977 – Michael Cole Oct 13 '16 at 00:24
  • 19
    This is the strangest page I've seen on StackOverflow. If you read the question carefully, only one answer even begins to attempt to answer what is actually being asked, and it has a score of -6. The highest scoring answer, which was accepted, not only doesn't answer, but is simply wrong. –  Apr 04 '17 at 15:31

32 Answers32

2581

Iterating over properties requires this additional hasOwnProperty check:

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

It's necessary because an object's prototype contains additional properties for the object which are technically part of the object. These additional properties are inherited from the base object class, but are still properties of obj.

hasOwnProperty simply checks to see if this is a property specific to this class, and not one inherited from the base class.


It's also possible to call hasOwnProperty through the object itself:

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

But this will fail if the object has an unrelated field with the same name:

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

That's why it's safer to call it through Object.prototype instead:

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true
Lambda Fairy
  • 13,814
  • 7
  • 42
  • 68
  • 24
    @B T According to the [Mozilla documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FStatements%2Ffor...in): "If you only want to consider properties attached to the object itself, and not its prototypes, use getOwnPropertyNames **or perform a hasOwnProperty check** (propertyIsEnumerable can also be used)." – davidmdem Aug 06 '13 at 19:47
  • 3
    What exactly is the point of calling `object.hasOwnProperty()`? Doesn't the fact that `property` has whatever value imply that its in `object`? – Alex S Apr 21 '14 at 19:48
  • 7
    Because, Alex S, an object's prototype contains additional properties for the object which are technically part of the object. They are inherited from the base object class, but they are still properties. hasOwnProperty simply checks to see if this is a property specific to this class, and not one inherited from the base class. A good explanation: http://brianflove.com/2013/09/05/javascripts-hasownproperty-method/ – Kyle Richter Apr 28 '14 at 20:02
  • 95
    I feel that I should mention, however, that Object.keys(obj) is now a much better solution for getting the keys of the object itself. Link to the Mozilla documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – Kyle Richter Apr 28 '14 at 20:07
  • If you like performance, you won't use hasOwnProperty. You'll add non-enumerable properties the proper way using Object.defineProperty – Adria Oct 11 '14 at 04:05
  • 2
    if('javascript'.hasOwnProperty(0)) console.log('Well, you've really just screwed me over, didn't you, javascript?'); –  Jan 28 '16 at 14:10
  • Please look at the example of @Will just above me. This answer is not correct. If your object is a string, the solution given by this answer will not work. Just try the following: `for (var property in 'javascript') console.log(property)` – Jadiel de Armas Jan 28 '16 at 20:04
  • @JadieldeArmas strings are just a corner case you have to watch out for. Like everything else in javascript :/ –  Jan 28 '16 at 20:09
  • 1
    I think that the confusion is mainly introduced here because a Javascript object and a JSON object are not the same thing. – Jadiel de Armas Jan 28 '16 at 20:23
  • 4
    @Rafay I really don't understand how this answer has anything to do with the actual question. The loop does not show any inherited properties unless the OP has modified `Object.prototype`. This may be good advice but you yourself said `I couldn't get my head around "looping through object properties"`. Many chose not to add a `hasOwnProperty` check. If you created the object yourself and you haven't added some dumb library that adds properties to `Object.Prototype` there's no need for such check. – Ruan Mendes Feb 26 '16 at 13:24
  • 9
    One important piece of information is missing. `property` is a string here, should have been called `propertyName`. Otherwise can cause confusion for JS newbies like myself, i.e. what to do inside the `if`. – Victor Zakharov Jul 20 '16 at 15:57
  • 2
    This answer needs to be updated for "ES7", with methods such as `Object.entries` and `Object.values`. –  Sep 13 '16 at 09:07
  • 1
    If you don't need to support IE8 and you're only using well-behaved libraries that don't define enumerable properties on Object.prototype, there is no longer a reason to use hasOwnProperty when looping through properties. Now that I have control over whether I want a property to be enumerable, respect my choices, and don't disallow me from using inheritance for no good reason. – JounceCracklePop Dec 30 '16 at 02:28
  • 1
    This answer is completely unrelated to the question, and is in fact very misleading. Fine if one wants to use `.hasOwnProperty()`, but it falls under the same category of *"what if something corrupts my environment"*, which begs the question... what if `.hasOwnProperty` itself was corrupted. Much of the time a good developer can ensure the environment is clean, making this totally unnecessary. –  Apr 04 '17 at 15:42
  • 3
    this doesn't answer the question at all. why 1700 people upvote it? – brettwhiteman Sep 30 '17 at 01:51
  • 1
    These are the same values returned from `Object.keys(obj)` – Meghan Mar 11 '18 at 14:19
1312

As of JavaScript 1.8.5 you can use Object.keys(obj) to get an Array of properties defined on the object itself (the ones that return true for obj.hasOwnProperty(key)).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

This is better (and more readable) than using a for-in loop.

Its supported on these browsers:

  • Firefox (Gecko): 4 (2.0)
  • Chrome: 5
  • Internet Explorer: 9

See the Mozilla Developer Network Object.keys()'s reference for futher information.

SetFreeByTruth
  • 819
  • 8
  • 23
Danny R
  • 13,734
  • 1
  • 15
  • 12
  • 8
    This is now more widely supported: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – Dom Vinyard Jan 29 '14 at 14:00
  • 3
    And if you need support for old browsers, you can use this [polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Polyfill) – KyleMit May 05 '14 at 15:55
  • 27
    In environments that support this language construct, this method allows Array.foreach to be called: `Object.keys(myObject).forEach(function(key,index) { //key = the name of the object key //index = the ordinal position of the key within the object });` – Todd Price Nov 06 '14 at 18:46
  • Tried this in MSIE 9.0 but it doesn't recognize Object.keys() – Victor Grazi Nov 26 '14 at 20:26
  • Tiny polyfill for IE 9 and below: `if( !Object.keys ){ Object.keys = function( o ){ var p, k = []; for( p in o ){ if( Object.prototype.hasOwnProperty.call( o, p ) ){ k.push( p ); } return k; }; }` – Beejor Sep 21 '16 at 04:47
  • Thanks, this helped me. I needed a solution to determine the end of the loop, which was impossible with for-in. Now that I can check against the array of keys it is easy. Thanks again! – Megajin Nov 09 '16 at 09:41
  • 2
    Good solution. But how to break the iteration?! – AJ_83 Jan 25 '17 at 08:19
  • 4
    @AJ_83 There's no good way to break out of a forEach(). Use some() in this case, and return true to break – Daniel Z. Mar 23 '17 at 10:47
  • 16
    why is this more readable than for-in? `for candidate in candidateStatus`... seems readable to me – Jona Jul 30 '18 at 11:48
  • 1
    notice that using `Object.keys` changes the order of the keys, and sorts them, so if you care about the order of items in the object, you should use the accepted answer – alostr Mar 17 '19 at 15:20
  • 2
    It surprises me that anyone would find this syntax "more readable". I guess it all depends what your background is, but for me it's hard to beat the for(loop control here) { do stuff here } syntax. That structure has been around in various languages since before most people on StackExchange were born. The javascript structure, with a function call as an argument, is rather new, in the grand scheme of things. – Duncan May 17 '19 at 21:21
  • @Duncan Because of the atrocious "hasOwnProperty" malarkey. – corsiKa Jan 12 '21 at 05:13
376

Girls and guys we are in 2019 and we do not have that much time for typing... So lets do this cool new fancy ECMAScript 2016:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));
Frank Roth
  • 6,191
  • 3
  • 25
  • 33
  • 23
    How is this any different than Danny R's answer? – krillgar Jan 11 '17 at 15:37
  • 28
    It is a oneliner and uses map instead of forEach. And also the console.log satement is maybe interesting for some people. – Frank Roth Jan 12 '17 at 16:08
  • Satly, that doesn't work when `obj=window.performance.memory` :-/ Where as `for in` does. i.e. `var obj = window.performance.memory; for( key in obj ) console.log( 'key=' + key + ' val=' + obj[key] );` – Michaelangel007 Feb 01 '17 at 23:34
  • 2
    `window.performance.memory` is only supported by chrome and `Object.keys(obj)` returns an empty array. This has nothing to do with `.map`. – Frank Roth Feb 02 '17 at 09:40
  • In case anyone doesn't want to monkey around re-structuring this single-liner to do more than one thing at a time with `e`, I've posted this gist. It's basically just like most hash implementations, and uses `(` `(key)` `=>` `(value)` `)` instead of `{` `key` `=>` `value` `}`, but if you haven't had to deal with that before, it could help you visualize it better: https://gist.github.com/the-nose-knows/9f06e745a56ff20519707433e28a4fa8 – kayleeFrye_onDeck Apr 19 '17 at 19:11
  • There is a difference: https://stackoverflow.com/questions/34426458/js-learning-difference-between-foreach-and-map – Frank Roth Oct 01 '17 at 15:00
  • You can trim two more characters from Grant's proposal by removing the parentheses for `log`: `Object.keys(obj).map(e => console.log\`key=${e} value=${obj[e]}\`)`. – Yay295 Nov 16 '17 at 04:59
  • Putting variables as separate arguments for `console.log` will often display more information (color formatting, the ability to expand objects, etc.), so this is better IMO: `Object.keys(obj).forEach(e => console.log('key=', e, 'value=', obj[e]));` – Luke Dec 03 '18 at 16:52
257

In up-to-date implementations of ES, you can use Object.entries:

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

or

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

If you just want to iterate over the values, then use Object.values:

for (const value of Object.values(obj)) { }

or

Object.values(obj).forEach(value => ...)
OneHoopyFrood
  • 3,829
  • 3
  • 24
  • 39
  • 1
    this would be the best solution (object.entries...), but I can't use it. When you want to do this multiple times and can't support it in your framework, you can use the polyfill on this page: https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Object/entries – Mario Oct 04 '17 at 08:21
  • The third suggestion is great if you only the properties' values. Awesome! – gnzg Apr 24 '18 at 16:02
  • this is best answer, you should use `for (const [key, value] of Object.entries(obj)) { }` – OzzyCzech Jul 28 '21 at 07:41
228

It's the for...in statement (MDN, ECMAScript spec).

You can read it as "FOR every property IN the obj object, assign each property to the PROPT variable in turn".

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 1
    Thanks a lot, I understand it now. I was banging my head, going through books and Google. – Rafay Nov 29 '11 at 14:43
  • 21
    Agree with @RightSaidFred, the `in` operator and the `for` statement are not involved at all, the [`for-in` statement](http://es5.github.com/#x12.6.4) represents a grammar production on its own: `for ( LeftHandSideExpression in Expression )`, `for ( var VariableDeclarationNoIn in Expression )` – Christian C. Salvadó Nov 29 '11 at 15:08
  • 2
    Odd this answer has so many up votes, especially since these popular comments seem to contradict it. – Doug Molineux Aug 22 '13 at 21:46
  • @PaulCarroll, that is incorrect. for each is different. This is what you're looking for: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FStatements%2Ffor...in – Danation Oct 14 '13 at 15:40
  • 10
    Why is this marked as the answer? It is quite possibly the least helpful one in this thread.. – computrius Dec 12 '13 at 17:48
  • 1
    @PeteHerbertPenito, odd that nobody bothered to edit the answer until [I did](http://stackoverflow.com/posts/8312494/revisions). – Dan Dascalescu Apr 17 '14 at 08:09
  • 3
    Least helpful answer? Depends what you think the OP was asking; when I first read the question it seemed like baffled bemusement about the mechanism by which a variable can be used to inspect an object's properties, and which _this_ answer explains eloquently (the 'for-in' misnomer notwithstanding). The question "Why does it come up with every property" I see could imply the OP was looking for hasOwnProperty but doesn't know it, but I think it's more likely _this_ was what the OP wanted to know, and has incorrectly accepted a correct answer to a different question. :-) – Bumpy Sep 21 '16 at 09:13
  • This is the first answer I've found that actually answers the question. – David Callanan Sep 01 '18 at 18:08
  • 1
    "For *each* property in the object". One of my pet peeves is messing up plurality. It's so confusing to beginners. – Tom Russell Nov 28 '18 at 20:05
  • This answer does not iterate through the list of objects, rather they key names of each object and the return value is a string. – Ian Steffy Jan 23 '19 at 13:31
  • 1
    @IanS - sounds like you are looking for "how to iterate through the *items* in an *array*". *This* Q&A is about "how to iterate through the *properties* of an *Object*". In JavaScript, unlike some other languages, two different syntaxes are required for these cases. For array items, use `for .. of`, **not** `for .. in`. – ToolmakerSteve Oct 12 '19 at 12:00
44

It's just a for...in loop. Check out the documentation at Mozilla.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
39
if (typeof obj === 'object' && obj !== null) {
    Object.keys(obj).forEach(key => {
        console.log("\n" + key + ": " + obj[key]);
    });
}

// *** Explanation line by line ***

// Explaining the bellow line
// It checks if obj is neither null nor undefined, which means it's safe to get its keys. 
// Otherwise it will give you a "TypeError: Cannot convert undefined or null to object" if obj is null or undefined when it tries to get its keys in the next line of code.
// NOTE 1: You can use Object.hasOwnProperty() instead of Object.keys(obj).length
// NOTE 2: No need to check if obj is an array because it will work just fine.
// NOTE 3: No need to check if obj is a string because it will not pass the 'if typeof obj is Object' statement.
// NOTE 4: No need to check if Obj is undefined because it will not pass the 'if type obj is Object' statement either.
if (typeof obj === 'object' && obj !== null) {

    // Explaining the bellow line
    // Just like in the previous line, this returns an array with
    // all keys in obj (because if code execution got here, it means 
    // obj has keys.) 
    // Then just invoke built-in javascript forEach() to loop
    // over each key in returned array and calls a call back function 
    // on each array element (key), using ES6 arrow function (=>)
    // Or you can just use a normal function ((key) { blah blah }).
    Object.keys(obj).forEach(key => {

        // The bellow line prints out all keys with their 
        // respective value in obj.
        // key comes from the returned array in Object.keys(obj)
        // obj[key] returns the value of key in obj
        console.log("\n" + key + ": " + obj[key]);
    });
}
Fouad Boukredine
  • 1,495
  • 14
  • 18
  • 3
    Hi, could you add more information about your answer, providing only code does not help. – Nicolas Nov 12 '19 at 20:19
  • Hi @Nicolas I've added a line by line explanation to the code. Let me know if it's still not clear – Fouad Boukredine Nov 12 '19 at 23:18
  • 5
    Because `forEach` [skips empty values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), I think you could get rid of the if and just do `Object.keys(obj).forEach(e => console.log(\`key=${e} value=${obj[e]}\`));` like Frank Roth's answer. – Darkproduct Dec 18 '19 at 16:48
31

If your environment supports ES2017 then I would recommend Object.entries:

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

As shown in Mozillas Object.entries() documentation:

The Object.entries() method returns an array of a given object's own enumerable property [key, value] pairs, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

Basically with Object.entries we can forgo the following extra step that is required with the older for...in loop:

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}
JSON C11
  • 11,272
  • 7
  • 78
  • 65
26

Dominik's answer is perfect, I just prefer to do it that way, as it's cleaner to read:

for (var property in obj) {
    if (!obj.hasOwnProperty(property)) continue;

    // Do stuff...
}
Cyril N.
  • 38,875
  • 36
  • 142
  • 243
22

jquery allows you to do this now:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});
Rob Sedgwick
  • 4,342
  • 6
  • 50
  • 87
  • 2
    `$.each({foo:1, length:0, bar:2}, function(k,v){console.log(k,v)})` $.each is [not suitable](https://github.com/jquery/jquery/issues/3588#issuecomment-288682581) for objects. If an object happens to have a length property and its value happens to be zero, the whole object is treated as if it were an empty array. – Bob Stein Apr 04 '18 at 12:25
  • 1
    [Details](https://stackoverflow.com/a/49652688/673991) why I think this is a **bug-inviting approach**. – Bob Stein Apr 04 '18 at 14:43
21

The for...in loop represents each property in an object because it is just like a for loop. You defined propt in the for...in loop by doing:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

A for...in loop iterates through the enumerable properties of an object. Whichever variable you define, or put in the for...in loop, changes each time it goes to the next property it iterates. The variable in the for...in loop iterates through the keys, but the value of it is the key's value. For example:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

You can see how the variable differs from the variable's value. In contrast, a for...of loop does the opposite.

I hope this helps.

Vappor Washmade
  • 423
  • 4
  • 14
20
let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).forEach((item) => {console.log("item", obj[item])})

// a
// 3
// 2
Philll_t
  • 4,267
  • 5
  • 45
  • 59
  • 3
    As mentioned in other comments, `forEach` is more appropriate here, as `map` is intended to return a new array with the results of calling the code block on each iteration. But we are only interested in the side affects of each iteration, not the return value, hence we don't need that new array that `map` gives us. – Danny Nov 11 '18 at 03:13
19

To add ES2015's usage of Reflect.ownKeys(obj) and also iterating over the properties via an iterator.

For example:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

can be iterated over by

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

If you would like to iterate directly over the values of the keys of an object, you can define an iterator, just like JavaScipts's default iterators for strings, arrays, typed arrays, Map and Set.

JS will attempt to iterate via the default iterator property, which must be defined as Symbol.iterator.

If you want to be able to iterate over all objects you can add it as a prototype of Object:

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

This would enable you to iterate over the values of an object with a for...of loop, for example:

for(val of obj) { console.log('Value is:' + val ) }

Caution: As of writing this answer (June 2018) all other browsers, but IE, support generators and for...of iteration via Symbol.iterator

Dimitar Nikovski
  • 973
  • 13
  • 15
  • 1
    Although you are not actually answering the OP's question, this was very helpful for me, I did not know about Reflect yet. – Michiel May 29 '19 at 09:41
18

The above answers are a bit annoying because they don't explain what you do inside the for loop after you ensure it's an object: YOU DON'T ACCESS IT DIRECTLY! You are actually only delivered the KEY that you need to apply to the OBJ:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

This is all ECMA5 safe. Even works in the lame JS versions like Rhino ;)

dylanh724
  • 948
  • 1
  • 12
  • 29
  • `shouldBeBar` is undefined for all three iterations. – Antony Hatchkins Jul 15 '20 at 18:17
  • `undefined` is impossible since it's, well, clearly defined in front of you :) This deducts to 2 possibilities: (1) Are you checking for shouldBeBar OUTSIDE of the if() block? Then yes, it will be undefined (out of scope). Or (2) Did you typo the var name? – dylanh724 Jul 17 '20 at 06:49
16

You can access the nested properties of the object using the for...in and forEach loop.

for...in:

for (const key in info) {
    console.log(info[key]);
}

forEach:

Object.keys(info).forEach(function(prop) {
    console.log(info[prop]);
    // cities: Array[3], continent: "North America", images: Array[3], name: "Canada"
    // "prop" is the property name
    // "data[prop]" is the property value
});
Sunny
  • 1,286
  • 12
  • 16
14

You can use Lodash. The documentation

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
viktarpunko
  • 354
  • 2
  • 11
  • 11
    Why on earth does this "answer" have 10 upvotes? It completely fails to answer the question. I'm beginning to lose faith in the intelligence on the average JS developer. – brettwhiteman Sep 30 '17 at 01:53
  • 1
    @developerbmw I understand that using ES6 features is more right way, but I've answered a year ago. Please, share your thoughts with us when you have a minute. – viktarpunko Oct 02 '17 at 08:20
  • 1
    The idea is to focus more on native methods, instead of suggesting the user add a 10000 line library to their page. Don't get me wrong, I do like using Lodash but there's a time and a place for it and it isn't this. –  Jun 19 '18 at 19:58
  • @user9016207 this answer is from 2016, and was more applicable then - esp if you were already using lodash. nowadays if you need individual fns from lodash you can get them one at a time, eg https://www.npmjs.com/package/lodash.keys – Brian Burns Sep 11 '20 at 15:21
13
Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);
Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
12

Nowadays you can convert a standard JS object into an iterable object just by adding a Symbol.iterator method. Then you can use a for of loop and acceess its values directly or even can use a spread operator on the object too. Cool. Let's see how we can make it:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);
Redu
  • 25,060
  • 6
  • 56
  • 76
11

Your for loop is iterating over all of the properties of the object obj. propt is defined in the first line of your for loop. It is a string that is a name of a property of the obj object. In the first iteration of the loop, propt would be "name".

arb
  • 7,753
  • 7
  • 31
  • 66
10

Objects in JavaScript are collections of properties and can therefore be looped in a for each statement.

You should think of obj as an key value collection.

  • ! with the important difference that these 'lists of properties' can have names as keys, while normal JS arrays can only have numbers as keys. – Qqwy Nov 29 '11 at 14:38
7

If running Node I'd recommend:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});
Justin
  • 42,716
  • 77
  • 201
  • 296
6

While the top-rated answer is correct, here is an alternate use case i.e if you are iterating over an object and want to create an array in the end. Use .map instead of forEach

const newObj = Object.keys(obj).map(el => {
    //ell will hold keys 
   // Getting the value of the keys should be as simple as obj[el]
})
Alwaysblue
  • 9,948
  • 38
  • 121
  • 210
5

I want to add to the answers above, because you might have different intentions from Javascript. A JSON object and a Javascript object are different things, and you might want to iterate through the properties of a JSON object using the solutions proposed above, and then be surprised.

Suppose that you have a JSON object like:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", "value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

The wrong way to iterate through its 'properties':

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

You might be surprised of seeing the console logging 0, 1, etc. when iterating through the properties of prop1 and prop2 and of prop3_1. Those objects are sequences, and the indexes of a sequence are properties of that object in Javascript.

A better way to recursively iterate through a JSON object properties would be to first check if that object is a sequence or not:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }
            
     }
}
Joe Johnston
  • 2,794
  • 2
  • 31
  • 54
Jadiel de Armas
  • 8,405
  • 7
  • 46
  • 62
4

What for..in loop does is that it creates a new variable (var someVariable) and then stores each property of the given object in this new variable(someVariable) one by one. Therefore if you use block {}, you can iterate. Consider the following example.

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet
Raman Sohi
  • 101
  • 1
  • Upvoting this, given it's simplicity. In my use case I need to check all the attributes in an object for dodgy values-NaNs, nulls, undefined (they were points on a graph and these values prevented the graph from drawing). To get the value instead of the name, in the loop you would just do `obj[someVariable]`. Perhaps the reason it was downvoted so much is because it is not recursive. So this would not be an adequate solution if you have a highly structured object. – Katharine Osborne Apr 27 '18 at 09:50
  • @KatharineOsborne or perhaps it is because the following phrase is a bit cryptic: "Therefore if you use block {}, you can iterate." The code says more than the text. – bvdb Jul 02 '19 at 09:11
4

Also adding the recursive way:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

Usage:

iterate({ foo: "foo", bar: { foo: "foo"} }); 
Ondrej Svejdar
  • 21,349
  • 5
  • 54
  • 89
  • 1
    @faiz - see my comments, it is safeguard against being stuck in endless loop when you recurrently walk trough object that has cyclic references – Ondrej Svejdar Feb 22 '16 at 08:36
4

Here I am iterating each node and creating meaningful node names. If you notice, instanceOf Array and instanceOf Object pretty much does the same thing (in my application, i am giving different logic though)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

note - I am inspired by Ondrej Svejdar's answer. But this solution has better performance and less ambiguous

Faiz Mohamed Haneef
  • 3,418
  • 4
  • 31
  • 41
4

You basically want to loop through each property in the object.

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);
HovyTech
  • 299
  • 5
  • 19
1

To further refine the accepted answer it's worth noting that if you instantiate the object with a var object = Object.create(null) then object.hasOwnProperty(property) will trigger a TypeError. So to be on the safe side, you'd need to call it from the prototype like this:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}
Konrad Kiss
  • 6,856
  • 1
  • 20
  • 21
1

Check type

You can check how propt represent object propertis by

typeof propt

to discover that it's just a string (name of property). It come up with every property in the object due the way of how for-in js "build-in" loop works.

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(typeof propt,  propt + ': ' + obj[propt]);
}
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
0

If you just want to iterate to map property values then lodash has _.mapValues

const obj = {
  a: 2,
  b: 3
}
const res = _.mapValues(obj, v => v * 2)
console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
danday74
  • 52,471
  • 49
  • 232
  • 283
0

If you have an array of objects with their properties e.g

let students = [{name:"John", gender:"male", yob:1991},{name:"Mary", gender:"female", yob:1994} ]

You can iterate over the properties in 2 ways

  1. Using the for of loop in Javascript

    for(let student of students){
    
     //access the properties here
    
     student.name
     student.gender
     student.yob
    
    
    
     }
    
  2. Using the for each loop in Javascript

 students.forEach(function(value, index, arr){
  //access properties here
  value.name
  value.gender
  value.yob


 });

-1

Simple and clear way to reach this, im modern JS without iterate the prototypes, is like this:

Object.prototype.iterateProperties = ((callback) => {
   Object.keys(obj).filter(key => obj.hasOwnProperty(key)).forEach((key) => {
      callback(key, obj[key]);
   });
});

Explain

This code creates a function in the prototype of all object - means function that is accessible in every Object instance. The function iterate all own properties of the object and run a callback function which gets (key, value) for each propery in the object.

Example for use

obj.iterateProperties((key, value) => console.log(key + ': ' + value));
  • 1
    You are iterating over the same object two times, this is not a correct way to do this. Please update this answer merging all in one forEach, because this is a propagation of bad practices. – Ernesto Alfonso Nov 23 '21 at 20:44