How does Object.entries() work? Unexpected console.log output

I’ve got object of objects:

let obj = {
  a: {
    af: {
      key: "k", val: "v"
    },
    bf: {
      key: "g", val: "h"
    }
  },
  b: {
    af: {
      key: "f", val: "w"
    },
    nf: {
      key: "u", val: "t"
    }
  }
};`

I’m trying to get an array of all values associated with key – in this case: ["k","g","f","u"] I tried to use Object.entries() in the for loop but I guess I do not understand how it works. I did simply as in docs:

for ([k,v] in Object.entries(obj)){
  console.log(k,v)
}

but my result is

0 undefined

1 undefined

which I completly do not understand. Could you please help me with explaining how this short code works?

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

for ([k,v] in Object.entries(obj)){
  console.log(k,v)
}

Answer

Object.entries(obj) returns an array. Each item in the array represents one property of the object expressed as an array containing the property name and the property value.

x in someObject gets the iterable property names of the object.

The property names in an array are the numerical indexes.

Hence your output:

const [x,y] = "0";
console.log({x,y});

If you want to loop over the property values instead of the property names you need of (which loops over the values) not in.

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

for ([k,v] of Object.entries(obj)){
  console.log(k,v)
}

However, looping over an array should probably be done using forEach (or a traditional three-part for loop) instead, as it won’t trip over unexpected enumerable properties that might be added to your array.

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

Object.entries(obj).forEach( ([k,v]) => console.log({k,v}) );