Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The for...in statement iterates over all enumerable string properties of an object, including those inherited through its prototype chain. It explicitly ignores properties keyed by Symbol.
for (variable in object) {
  // statements
}
  • variable: A different property name (key) is assigned to this variable on each iteration. It is typically declared with const or let.
  • object: The object whose enumerable properties are being evaluated.

Technical Mechanics

Prototype Chain Traversal Unlike Object.keys(), which only returns an object’s own enumerable properties, for...in traverses the object’s prototype chain. It will yield inherited enumerable properties unless they are shadowed by a property on the instance itself. Iteration Order While historically implementation-dependent, modern JavaScript engines (ES2015+) follow a deterministic enumeration order:
  1. Non-negative integer keys (often called “array indices”) in ascending numeric order.
  2. String keys in chronological order of property creation.
  3. Inherited properties, following the same rules (integers, then strings) for each prototype in the chain.
Type Coercion All yielded keys are strictly of type String. Even if a property was defined using a numeric literal, for...in will coerce and yield it as a string.

Behavior Visualization

const parent = { inherited: 'value' };
const child = Object.create(parent);

child.b = 1;
child[10] = 2;
child[2] = 3;
child.a = 4;

for (const key in child) {
  console.log(key);
}

// Output:
// "2"         (Integer key, ascending)
// "10"        (Integer key, ascending)
// "b"         (String key, insertion order)
// "a"         (String key, insertion order)
// "inherited" (Prototype chain property)

Critical Caveats

Filtering Inherited Properties Because for...in walks the prototype chain, it is standard practice to guard the execution block to ensure the property belongs directly to the instance. This is done using Object.hasOwn() (or Object.prototype.hasOwnProperty.call() in older environments).
for (const key in object) {
  if (Object.hasOwn(object, key)) {
    // Executes only for the object's own properties
  }
}
Array Iteration Anti-Pattern Using for...in to iterate over Array objects is considered a severe anti-pattern for three reasons:
  1. It yields array indices as strings ("0", "1", "2") rather than numbers, which can lead to unintended string concatenation in mathematical operations.
  2. It will iterate over any custom properties attached to the array object (e.g., myArray.customProp = true).
  3. If a library or polyfill mutates Array.prototype to add enumerable methods, for...in will yield those methods as keys during iteration.
Master JavaScript with Deep Grasping Methodology!Learn More