Rafay
Rafay

Reputation: 24265

Iterate through object properties

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?

Upvotes: 2387

Views: 1675026

Answers (30)

Fouad Boukredine
Fouad Boukredine

Reputation: 1623

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]);
    });
}

Upvotes: 40

Isaac Sichangi
Isaac Sichangi

Reputation: 75

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


 });

Upvotes: -1

Jadiel de Armas
Jadiel de Armas

Reputation: 8792

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]);

            }
            
     }
}

Upvotes: 5

user17344058
user17344058

Reputation:

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));

Upvotes: -2

danday74
danday74

Reputation: 56936

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/[email protected]/lodash.min.js"></script>

Upvotes: 0

Philll_t
Philll_t

Reputation: 4437

let obj = {"a": 3, "b": 2, "6": "a"}

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

// a
// 3
// 2

Upvotes: 20

Sunny
Sunny

Reputation: 1456

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
});

Upvotes: 17

Matt Ball
Matt Ball

Reputation: 359776

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

Upvotes: 44

Cyril N.
Cyril N.

Reputation: 39859

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...
}

Upvotes: 26

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92347

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]);
}

Upvotes: 0

user663031
user663031

Reputation:

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 => ...)

Upvotes: 276

Frank Roth
Frank Roth

Reputation: 6339

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]}`));

Upvotes: 387

Alwaysblue
Alwaysblue

Reputation: 11830

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]
})

Upvotes: 6

user2417527
user2417527

Reputation:

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

Upvotes: 2600

Dimitar Nikovski
Dimitar Nikovski

Reputation: 973

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

Upvotes: 19

Fellow Stranger
Fellow Stranger

Reputation: 34013

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

Upvotes: 14

Danny R
Danny R

Reputation: 14024

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.

Upvotes: 1340

dylanh724
dylanh724

Reputation: 1018

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 ;)

Upvotes: 18

JSON C11
JSON C11

Reputation: 11792

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
}

Upvotes: 31

Konrad Kiss
Konrad Kiss

Reputation: 6877

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
    }
}

Upvotes: 1

Justin
Justin

Reputation: 45320

If running Node I'd recommend:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});

Upvotes: 7

viktarpunko
viktarpunko

Reputation: 353

You can use Lodash. The documentation

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});

Upvotes: 14

Redu
Redu

Reputation: 26161

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);

Upvotes: 12

HovyTech
HovyTech

Reputation: 389

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);

Upvotes: 4

Rob Sedgwick
Rob Sedgwick

Reputation: 4514

jquery allows you to do this now:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});

Upvotes: 22

Ondrej Svejdar
Ondrej Svejdar

Reputation: 22054

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"} }); 

Upvotes: 4

Faiz Mohamed Haneef
Faiz Mohamed Haneef

Reputation: 3596

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

Upvotes: 4

Vappor Washmade
Vappor Washmade

Reputation: 453

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.

Upvotes: 23

Raman Sohi
Raman Sohi

Reputation: 101

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

Upvotes: 4

Marc B
Marc B

Reputation: 360562

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".

Upvotes: 232

Related Questions