Glossary / Property enumeration

Property enumeration

Property enumeration visits object keys, but JavaScript APIs select different subsets: own or inherited, enumerable or non-enumerable, string keys or Symbols. Understanding the differences is necessary for copying, serialization, validation, and reflection. Enumeration order is defined for ordinary objects, but it is not always simple insertion order.

API selection

API Own only? Enumerable only? Symbols? Inherited?
Object.keys Yes Yes No No
Object.getOwnPropertyNames Yes No No No
Object.getOwnPropertySymbols Yes Either Yes No
Reflect.ownKeys Yes Either Yes No
for...in No Yes No Yes

For ordinary objects, integer-index-like string keys are enumerated first in ascending numeric order, then other string keys in creation order, then Symbols in creation order. for...in walks the prototype chain and should usually be guarded with Object.hasOwn when only own data is intended. Array holes are absent properties and will not appear in Object.keys.

Object spread and Object.assign copy enumerable own string and Symbol keys; JSON serialization follows its own rules and ordinarily serializes enumerable string keys. These differences matter when writing cloning, validation, or merge functions. Getters may execute during reads, and Proxies can customize own-key behavior subject to invariants.

Interview questions

  1. Does for...in include inherited keys? Yes, enumerable string keys on the prototype chain too.
  2. Does Object.keys include Symbols? No.
  3. Which API returns all own keys? Reflect.ownKeys includes strings and Symbols, enumerable and non-enumerable.
  4. Is enumeration exactly insertion order? Integer-index-like strings are ordered first numerically, then other strings, then Symbols.

References