albert.walickihire me
← all solutions
javascript

How to convert an object to an array in JavaScript?

Convert an object to an array with Object.keys, Object.values or Object.entries, go back with Object.fromEntries, and handle array-like objects.

Use Object.keys() for an array of the keys, Object.values() for the values, or Object.entries() for [key, value] pairs. All three return a new array and leave the object as it is.

const prices = { apple: 1.2, banana: 0.5, cherry: 3 };

Object.keys(prices);
// ['apple', 'banana', 'cherry']

Object.values(prices);
// [1.2, 0.5, 3]

Object.entries(prices);
// [['apple', 1.2], ['banana', 0.5], ['cherry', 3]]

Pick the one that matches what you need next. If you only sum the prices, Object.values is enough. If you need both the name and the price, use Object.entries.

Entries to an array of objects

APIs often return an object keyed by id or name, while a list component wants an array of objects. Destructure each pair in map:

const products = Object.entries(prices).map(([name, price]) => ({
  name,
  price,
}));
// [
//   { name: 'apple', price: 1.2 },
//   { name: 'banana', price: 0.5 },
//   { name: 'cherry', price: 3 }
// ]

The parentheses around { name, price } are needed, because an arrow function reads a bare { as the start of a function body.

Back to an object with Object.fromEntries

Object.fromEntries() does the opposite of Object.entries(). It takes an array of [key, value] pairs and builds an object:

const backToObject = Object.fromEntries(
  products.map(({ name, price }) => [name, price])
);
// { apple: 1.2, banana: 0.5, cherry: 3 }

Together they're the usual way to map over an object, since objects have no map method of their own:

const doubled = Object.fromEntries(
  Object.entries(prices).map(([name, price]) => [name, price * 2])
);
// { apple: 2.4, banana: 1, cherry: 6 }

Which keys are included

All three methods return only the object's own enumerable string keys. They skip:

  • inherited properties from the prototype,
  • properties defined as non-enumerable,
  • Symbol keys.
const base = { inherited: true };
const user = Object.create(base);
user.name = 'Ada';
user[Symbol('id')] = 42;
Object.defineProperty(user, 'secret', {
  value: 'hidden',
  enumerable: false,
});

Object.keys(user); // ['name']
user.inherited; // true, but it isn't in the array

For plain objects from JSON this never matters. It matters with class instances, where methods live on the prototype and won't show up.

Key order

The order is mostly insertion order, with one exception: keys that look like non-negative integers come first, sorted in ascending order. All keys also come back as strings.

const scores = { b: 1, 10: 'ten', a: 2, 2: 'two' };

Object.keys(scores);
// ['2', '10', 'b', 'a']

If order matters and your keys are numeric ids, don't rely on the object. Sort the array yourself after converting, or keep the data in an array or a Map, which always keeps insertion order.

Array-like objects and NodeList

An array-like object has a length and indexed keys, but no array methods. Object.values is the wrong tool here, because it includes length as a value:

const arrayLike = { length: 2, 0: 'a', 1: 'b' };

Object.values(arrayLike);
// ['a', 'b', 2]

Array.from(arrayLike);
// ['a', 'b']

The same goes for DOM collections. querySelectorAll returns a NodeList, which has forEach but no map or filter. Convert it with Array.from() or spread syntax:

const items = document.querySelectorAll('.menu li');

const labels = Array.from(items, (item) => item.textContent);

// or, the same with spread
const sameLabels = [...items].map((item) => item.textContent);

Array.from takes a mapping function as the second argument, so you can convert and map in one step.

more solutions
work with me

Got something that needs building?

Frontend builds, full-stack features in Django, design-system work. Available for work.

See my workGet in touch