What you'll be able to do

By the end of this page you should be able to list an object’s keys with Object.keys, its values with Object.values, and [key, value] pairs with Object.entries — then use normal array tools like map and filter on those results.

Previous post: objects basics.

Who this is for

  • People who try user.map(...) and get a TypeError
  • Beginners who write for...in for every walk and want a clearer “keys as a list” habit
  • Anyone building a small UI from an object of labels or counts

You can skip this if you already reach for Object.entries when you need both the name and the value. Come back when you catch yourself fighting an object as if it were an array.

Objects are not arrays

Arrays have indexes and methods like map. Plain objects have named keys. You do not call map on the object itself.

const user = { name: "Asha", role: "editor" };
// user.map(...) // TypeError — objects are not arrays

Scenario A — settings bag. Keys are theme, compact. You want a list of those names.

Scenario B — score tally. Keys are answer ids; values are numbers. You want to total the values.

First turn the object into an array of something, then use array methods.

Object.keys: the property names

const post = { title: "Objects", views: 12 };
console.log(Object.keys(post)); // ["title", "views"]

Scenario A — show which fields were filled. Object.keys(form).length.

Scenario B — check a key exists. Object.keys(post).includes("title") works, but Object.hasOwn(post, "title") (or "title" in post with care) is clearer for a single check.

Object.values: just the values

const scores = { a: 8, b: 10, c: 7 };
console.log(Object.values(scores)); // [8, 10, 7]
const total = Object.values(scores).reduce(function (acc, n) {
  return acc + n;
}, 0);

Scenario A — sum a tally object. Values → reduce (you already know reduce from arrays).

Scenario B — average of quiz section scores. Same idea: values first, then math.

Object.entries: key and value together

const labels = { save: "Save", cancel: "Cancel" };
Object.entries(labels).forEach(function (pair) {
  const key = pair[0];
  const value = pair[1];
  console.log(key + " → " + value);
});

Scenario A — render buttons from a map of ids to labels.

Scenario B — filter pairs. Keep only high scores:

const high = Object.entries(scores).filter(function (pair) {
  return pair[1] >= 9;
});
// [["b", 10]]

Destructuring in the callback is fine once you meet it next: .map(([key, value]) => ...). For now, pair[0] / pair[1] is enough.

Building a new object from entries

const doubled = Object.fromEntries(
  Object.entries(scores).map(function (pair) {
    return [pair[0], pair[1] * 2];
  }),
);

Scenario A — transform every value, keep the same keys.

Scenario B — you only needed a list for the UI. Stop at entries + map to strings; you do not always need fromEntries.

for...in vs keys/entries (quick)

for...in walks enumerable keys and can pick up inherited names if you are not careful. Object.keys / entries stick to the object’s own enumerable string keys in normal beginner cases.

Scenario A — your own literal { a: 1 }. Both styles work; keys/entries read more like “make a list, then loop.”

Scenario B — you already know for...of on arrays. Prefer for (const key of Object.keys(obj)) or for (const [key, value] of Object.entries(obj)) when you want that style.

A tiny practice file

Save as object-keys.html.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>keys values entries</title>
  </head>
  <body>
    <button id="go">Inspect scores</button>
    <pre id="out"></pre>
    <script>
      const scores = { html: 8, css: 9, js: 10 };
      document.getElementById("go").addEventListener("click", function () {
        const keys = Object.keys(scores);
        const values = Object.values(scores);
        const lines = Object.entries(scores).map(function (pair) {
          return pair[0] + ": " + pair[1];
        });
        document.getElementById("out").textContent =
          "keys: " + JSON.stringify(keys) + "\n" +
          "values: " + JSON.stringify(values) + "\n" +
          lines.join("\n");
      });
    </script>
  </body>
</html>

Mistakes I see a lot

1. Calling array methods on the object. Use keys/values/entries first.

2. Forgetting entries returns pairs. pair is an array of length 2.

3. Mutating while you walk keys. Prefer building a new object.

4. Assuming key order is a public API forever. Do not rely on order for critical logic; use arrays when sequence is the product.

5. Using for...in without knowing about inherited keys. Prefer Object.keys / entries as your default.

6. Object.keys on null. It throws — check the value first.

What to try before the next post

  1. Object.keys on a three-field user object.
  2. Sum Object.values of a small tally.
  3. Object.entries + map to "key=value" strings.
  4. Build the tiny HTML file.

Next in this series: destructuring objects and arrays — pull fields out safely without crashing on undefined.

Try this next outside the series

Objects and references click faster when you connect them to state, payloads, and database-shaped data.