0

Here I'm iterating over JSON objects stored inside a javascript object and print some of it's values.

 database.ref().once("value", function (snap) {
    //store javascript object containing JSON objects in scores variable.
    scores = snap.val();

    for(var key in scores){
        console.log(scores[key].Name);
    }
});

enter image description here

scores object look like this.

enter image description here

How does the for loop retrieve the key in each JSON object and store in the variable named "key"?

Since scores is not an array but a javascript object how does a for loop work at all?

For example scores[1].Name won't work. So, it's not index based.

Enzio
  • 799
  • 13
  • 32
  • Might find what you're looking for [here](https://stackoverflow.com/questions/684672/how-do-i-loop-through-or-enumerate-a-javascript-object). – csp713 Jan 03 '18 at 04:24
  • `for..in` is specifically for looping over the keys in an object, so that's why it works. That's what it's designed to do. – JLRishe Jan 03 '18 at 04:29

2 Answers2

2

In your example you have an object that looks like:

var obj = {
  'key1': {name: 'Josh', score: 9},
  'key2': {name: 'July', score: 30},
  'key3': {name: 'Joy', score: 18},
  'key4': {name: 'Barbara', score: 50},
};

Doing for (var key in obj) {...} will loop through all the keys of your initial object. In that example, that would be ['key1', 'key2', 'key3', 'key4'].

You are right to say that only array items can be access by index. For objects, children are accessed by keys (which are strings).

Both the following work:

// Directly when you know the key name
console.log(obj.key1.name); // Will print out 'Josh' 

// Using a variable when the key name is stored in a variable
var customKey = 'key1';
console.log(obj[customKey].name); // Will print out 'Josh' 

In your initial example, you are using the for ... in structure to loop through he object keys and then accessing the nested objects by key.

You can verify what I am saying with the following example:

database.ref().once("value", function (snap) {
    //store javascript object containing JSON objects in scores variable.
    scores = snap.val();

    for(var key in scores){
        console.log(key); // See what's inside your key variable
        console.log(scores[key].Name);
    }
});
klugjo
  • 19,422
  • 8
  • 57
  • 75
1

The for...in statement iterates over the enumerable properties of the given object.

Asuming you have the following object:

var o = { 
  a: 1, 
  b: 2, 
  c: { 
    d: 3 
  } 
};

Doing:

for (var key in o) console.log(key, o[key]);

Will print:

a 1
b 2
c { d: 3 }

I think it is important to keep in mind that the for...in statement also loops through the inherited properties of the object.

Doing:

o.__proto__.x = 4;
for (var key in o) console.log(key, o[key]);

Will print:

a 1
b 2
c { d: 3 }
x 4

If you want to loop only through the properties that belong to the object directly, and not to the prototype chain, you can use Object.keys():

var o = { 
  a: 1, 
  b: 2, 
  c: function () {}
};

o.__proto__.x = 4;
o.__proto__.y = function () {};

var keys = Object.keys(o);

for (var i = 0; i < keys.length; i++) console.log(keys[i], o[keys[i]]);

The code above prints:

a 1
b 2
c function () {} //functions are also enumerable
danypype
  • 443
  • 4
  • 10
  • Hi, can you explain why this is not working? `console.log(scores); console.log(scores[1]);` https://imgur.com/a/Ry7J0 – Enzio Jan 03 '18 at 07:02