Skip to content
Theory · Objects · lesson 3 of 13

Iterating over an object

When a line's label is known in advance, the form is read at one spot: prices.apple. But sometimes you have to go through the whole form without knowing its labels in advance. For example, to add up all the prices in the object prices.

Picture the form copied into a table: one column of labels, another of answers. A table can already be handled like a list. Three functions turn an object into an array for that:

JavaScript
const prices = { apple: 3, pear: 5, plum: 2 };

console.log(Object.keys(prices)); // [ 'apple', 'pear', 'plum' ]
console.log(Object.values(prices)); // [ 3, 5, 2 ]
console.log(Object.entries(prices)); // [ [ 'apple', 3 ], [ 'pear', 5 ], [ 'plum', 2 ] ]

Keys, values and pairs

Each function returns its own array:

  • Object.keys, an array of keys;
  • Object.values, an array of values;
  • Object.entries, an array of pairs.

Each pair is an array of two elements: the key at index 0 and the value at index 1. On the form, it is a strip of paper with a label and an answer written side by side.

All three arrays list the properties in the same order. So keys[i] and values[i] belong to one property.

Object.entries is handy when you need both the key and the value. In a pair entry, the key is entry[0] and the value is entry[1].

Iterating in a loop

The result is an ordinary array, so every array method works on it. An object has no length property, and the number of its properties is found with Object.keys(prices).length:

JavaScript
const total = Object.values(prices).reduce((sum, p) => sum + p, 0);
console.log(total, Object.keys(prices).length); // 10 3

for (const key in prices) {
    console.log(key, prices[key]);
}
// apple 3
// pear 5
// plum 2

Let's go through the example line by line:

  1. Object.values(prices) gives the array [3, 5, 2], and reduce adds it up to 10.
  2. Object.keys(prices).length is the length of the key array, that is, the number of properties: 3.
  3. The for…in loop goes over the object's keys: on each step, key holds the next key.
  4. The loop body prints the key and its value, one line per property.

Over an array, the for…in loop gives indexes; over an object, it gives keys. The value is read through square brackets: prices[key]. Writing prices.key does not work here: it looks for a property literally named key.

Key order

A key written as a number becomes a string: in the object { 2: "x" }, the key is "2". A key that looks like a non-negative whole number is called an integer-like key.

Every way of iterating gives the keys in the same order:

  1. integer-like keys first, in ascending numeric order;
  2. then the rest, in the order they were added.
JavaScript
const o = { b: 1, 10: 1, a: 1, 2: 1 };

console.log(Object.keys(o).join(" ")); // 2 10 b a

Let's see where this order comes from:

  • the key 10 comes after 2, although as a string "10" is less than "2": integer-like keys are compared as numbers;
  • b stays before a because it was added earlier;
  • the keys "01" and "-1" are not integer-like and go with the other strings.

Here the form stops helping. On paper, lines stay in the order they were written, while an object moves integer-like keys to the front. If the order of adding matters, do not rely on it in an object with integer-like keys: keep the elements in an array.

Interviewers like to check key order: they give an object with mixed keys and ask what Object.keys prints. The answer follows from the two rules above.

Common mistake

An object was iterated with for…of, like an array:

JavaScript
const prices = { apple: 3, pear: 5 };

for (const p of prices) { // ✗
    console.log(p);
}
TEXT
TypeError: prices is not iterable

for…of works with arrays and strings, but it cannot iterate over a plain object. The word iterable in the message means "can be iterated over": for…of accepts only such values.

Give it an array: for (const p of Object.values(prices)) gives the values, and for (const entry of Object.entries(prices)) gives the pairs.

Key points

  • Object.keys, Object.values and Object.entries turn an object into an array of keys, values or pairs.
  • An object has no length of its own: the number of properties is Object.keys(obj).length.
  • for…in over an object gives keys, and the value is read through obj[key].
  • Integer-like keys come first in ascending order, the rest in the order they were added.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way