Object.keys

Course 2 · Ch 1
Object.keys/values/entries and the Spread/Rest Operators
Turning objects into arrays you can already work with, and two compact syntaxes for copying and collecting values

Fundamentals Chapter 7 flagged that Object.keys() turns an object's property names into a real array — meaning Chapter 6's map/filter/reduce can be used on object data too. This chapter covers that properly, plus the spread (...) and rest (...) operators, which look identical but do opposite jobs depending on where they appear.

Object.keys, Object.values, Object.entries

const scores = { maths: 88, science: 72, art: 95 }; console.log(Object.keys(scores)); // ["maths", "science", "art"] console.log(Object.values(scores)); // [88, 72, 95] console.log(Object.entries(scores)); // [["maths", 88], ["science", 72], ["art", 95]]

Each of these returns a real array, unlocking everything from Chapter 6. entries() is the most useful for loops — each item is a [key, value] pair, which destructures neatly (covered below).

Combining Object.values with reduce

const total = Object.values(scores).reduce((sum, score) => sum + score, 0); console.log(total); // 255

This is the cleaner version of the Fundamentals Chapter 7 inventory challenge, which used a manual for...in loop with a separate running-total variable — here, reduce does both jobs in one expression.

Array Destructuring

const [first, second] = ["Alice", "Bob", "Carl"]; console.log(first); // "Alice" console.log(second); // "Bob" // Used directly in a loop over entries(): for (const [subject, score] of Object.entries(scores)) { console.log(`${subject}: ${score}`); }

Destructuring unpacks array elements straight into named variables in one line. for...of (a cousin of the for...in from Fundamentals Chapter 4/7) pairs naturally with entries(), since each entry is itself a two-element array ready to destructure.

Object Destructuring

const person = { name: "Philip", age: 35, city: "London" }; const { name, city } = person; console.log(name); // "Philip" console.log(city); // "London"

Object destructuring pulls named properties straight out into variables of the same name — far shorter than writing person.name and person.city on separate lines, especially useful for function parameters (see below).

The Spread Operator (...) — Expanding a Collection

const nums1 = [1, 2, 3]; const nums2 = [4, 5]; const combined = [...nums1, ...nums2]; console.log(combined); // [1, 2, 3, 4, 5] const original = { name: "Philip", age: 35 }; const updated = { ...original, age: 36 }; console.log(updated); // { name: "Philip", age: 36 } — original is untouched

Spread "unpacks" an array or object's contents into a new one. { ...original, age: 36 } copies every property from original, then overwrites age — a clean way to update one field without mutating the original object, the same non-mutating spirit as map/filter from Chapter 6.

The Rest Parameter (...) — Collecting the Leftovers

function sum(...numbers) { return numbers.reduce((total, n) => total + n, 0); } console.log(sum(1, 2)); // 3 console.log(sum(1, 2, 3, 4)); // 10

The exact same ... syntax, in a function's parameter list, does the opposite job: it gathers any number of arguments into a single real array (numbers), rather than expanding something. This is what lets sum() accept any number of arguments instead of a fixed count.

Same symbol, opposite meaning — context decides which
... in an array/object literal or function call is spread (expanding). ... in a function's parameter definition is rest (collecting). There's no separate keyword — only where it appears tells you which one it is.
ToolInputOutput
Object.keys(obj)ObjectArray of property names
Object.values(obj)ObjectArray of values
Object.entries(obj)ObjectArray of [key, value] pairs
{ ...obj, key: val }ObjectNew object, copied + overridden
function f(...args)Any number of argumentsA single real array, args

Coding Challenges

Challenge 1

Given const stock = { apples: 10, bananas: 5, oranges: 8 }, use Object.entries and a for...of loop with destructuring to log each item as "item: quantity", then use Object.values combined with reduce to log the total quantity.

📄 View solution
Challenge 2

Given const settings = { theme: "dark", fontSize: 14, notifications: true }, use the spread operator to create a new object updatedSettings with fontSize changed to 16, without modifying the original settings object. Log both objects to confirm settings is unchanged.

📄 View solution
Challenge 3

Write a function describeTeam(captain, ...players) that logs the captain's name on its own line, then logs every remaining player using a rest parameter and forEach. Call it with at least 4 names total.

📄 View solution

Chapter 1 Quick Reference (Intermediate)

  • Object.keys/values/entries — convert an object into a real array of names/values/pairs
  • Array/object destructuring — unpack values directly into named variables
  • for...of + Object.entries() — idiomatic way to loop over an object with both key and value
  • Spread (...) in a literal/call — expands a collection's contents (copying, merging, overriding)
  • Rest (...) in a parameter list — collects multiple arguments into one real array
  • Spread never mutates the original — same non-mutating principle as map/filter
  • Next chapter: closures — how a function can "remember" variables from where it was created