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:
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:
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 2Let's go through the example line by line:
Object.values(prices)gives the array[3, 5, 2], andreduceadds it up to10.Object.keys(prices).lengthis the length of the key array, that is, the number of properties:3.- The
for…inloop goes over the object's keys: on each step,keyholds the next key. - 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:
- integer-like keys first, in ascending numeric order;
- then the rest, in the order they were added.
const o = { b: 1, 10: 1, a: 1, 2: 1 };
console.log(Object.keys(o).join(" ")); // 2 10 b aLet's see where this order comes from:
- the key
10comes after2, although as a string"10"is less than"2": integer-like keys are compared as numbers; bstays beforeabecause 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:
const prices = { apple: 3, pear: 5 };
for (const p of prices) { // ✗
console.log(p);
}TypeError: prices is not iterablefor…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.valuesandObject.entriesturn an object into an array of keys, values or pairs.- An object has no
lengthof its own: the number of properties isObject.keys(obj).length. for…inover an object gives keys, and the value is read throughobj[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.