Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Loops and Control Flow  ›  Lesson

The for...in Loop

for...in loop 10 minfor...in walks an object's enumerable KEYS, not its values, and it also visits inherited keys, so it is the wrong tool for arrays, where for...of or a plain for loop is safer.

The for...in Loop

In short: for (const key in object) walks an object's enumerable keys — the labels, not what's inside the drawers. On a plain object that's exactly what you want. On an array, the keys are the string indices "0", "1", "2" — it often looks like it works, but it also visits any inherited enumerable property, which makes it the wrong tool for arrays. Use for...of or a plain for loop there instead.

A filing cabinet with three labelled drawers — title, plays, liked; for (const key in song) reads each label, one drawer at a time, giving you the key, not what's inside; a note warns that on an array the keys are string indices "0","1","2" and for...of is the better tool there

Printing every field of a song

for...in is built for exactly this: visiting an object's own properties without knowing their names in advance.

javascript

Each lap hands you a key — "title", "plays", "liked" — and song[key] reads the value that goes with it. This is the natural way to print or process an object whose exact shape you don't know ahead of time.

The array trap: keys are strings, not numbers

Run the same pattern on an array and it looks fine — until you check the type:

javascript

The keys are "0" and "1" — strings, not numbers. songs["0"] still works, because JavaScript converts the string back for you, but any arithmetic on index (like index + 1) would join text instead of adding, the same trap from the type-casting lessons.

Inherited keys show up too

The deeper reason for...in is risky on arrays: it walks every enumerable property, including ones inherited from further up the chain.

javascript

The first loop sees both "title" (the object's own) and "genre" (inherited from base) — a surprise if you only expected extended's own fields. Object.hasOwn(extended, key) filters to just the object's own properties, which is usually what you actually want.

Quick practice

quick drill

What does for (const key in { a: 1, b: 2 }) hand you on each lap?

quick drill

For const arr = ["x", "y"], what type is the index in for (const index in arr)?

quick drill

Why is for...in considered risky for looping over arrays?

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhy not for...in on an array?

A teammate loops over an array with for (const i in songs) { console.log(songs[i]); } and it seems to work. Explain what for...in actually gives you there, and why for...of or a plain for loop is the safer choice for arrays.