Volume 2

Q147: Object.hasOwn, Enumeration and Key Safety

Difficulty: SeniorFrequency: MediumAnswer time: 8-12 minutes

What Interviewers Want To Evaluate

This question checks whether you understand property ownership and safe object iteration. Interviewers want own properties, inherited properties, Object.hasOwn, Object.keys, for...in, symbols, non-enumerable properties, dictionaries, and prototype pollution risk.

Senior answers should connect key iteration to security and data correctness.

Short Interview Answer

Objects can have own properties and inherited properties. Object.hasOwn(obj, key) checks whether a key exists directly on the object. Object.keys returns own enumerable string keys, while for...in iterates enumerable keys including inherited ones. Reflect.ownKeys includes string and symbol own keys. For untrusted dictionaries, prefer Map or Object.create(null) and validate keys to avoid prototype-related surprises.

Detailed Interview Answer

Property access can find inherited values.

const child = Object.create({ role: "admin" });
child.name = "Asha";

console.log(child.role); // inherited

But ownership matters when iterating, merging, or validating data.

Own Properties

Own properties live directly on the object.

Object.hasOwn(child, "name"); // true
Object.hasOwn(child, "role"); // false

This is usually what you want when processing plain data payloads.

Object.hasOwn

Object.hasOwn is safer than calling obj.hasOwnProperty.

Object.hasOwn(obj, key);

It works even if the object has no prototype or has a shadowed hasOwnProperty field.

Object.keys

Object.keys returns own enumerable string keys.

const keys = Object.keys(obj);

It does not include inherited keys, non-enumerable keys, or symbol keys.

for...in

for...in iterates enumerable string keys, including inherited keys.

for (const key in obj) {
  if (Object.hasOwn(obj, key)) {
    process(obj[key]);
  }
}

If you only need own keys, prefer Object.keys.

Symbol Keys

Symbols can be property keys.

const id = Symbol("id");
const obj = { [id]: "u1" };

Use Object.getOwnPropertySymbols or Reflect.ownKeys when symbol keys matter.

Reflect.ownKeys

Reflect.ownKeys returns all own property keys:

own string keys
own symbol keys
enumerable and non-enumerable

This is useful for low-level utilities, but many app-level data loops should stay with Object.keys.

Non-Enumerable Properties

Some properties exist but do not show up in Object.keys.

Object.defineProperty(obj, "hidden", {
  value: true,
  enumerable: false,
});

This matters in libraries, descriptors, and debugging.

Dictionary Objects

Plain objects inherit from Object.prototype.

For arbitrary user-provided keys, consider:

const dictionary = Object.create(null);

Or use Map.

const dictionary = new Map();

Map is often clearer for arbitrary keys and avoids prototype key confusion.

Key Safety

When keys come from outside the system, validate them.

Dangerous keys include:

__proto__
constructor
prototype

This is connected to prototype pollution.

Common Mistakes

A common mistake is using for...in to merge untrusted data.

Another mistake is calling obj.hasOwnProperty(key) on an object that may not inherit that method.

Another mistake is forgetting symbol keys in low-level cloning or reflection utilities.

Senior Trade-Offs

Use the simplest key API that matches the goal.

app data fields: Object.keys
ownership check: Object.hasOwn
all own keys: Reflect.ownKeys
arbitrary dictionary: Map
untrusted object keys: validate or allowlist

Code or Design Example

function copyAllowedFields(source, allowedFields) {
  const result = {};

  for (const key of allowedFields) {
    if (Object.hasOwn(source, key)) {
      result[key] = source[key];
    }
  }

  return result;
}

Allowlisting fields is safer than copying everything.

Debugging Workflow

When object keys behave unexpectedly:

check own vs inherited property
check Object.keys output
check symbols with Reflect.ownKeys
check enumerability
check object prototype
check hasOwnProperty shadowing
check dangerous untrusted keys

Interview Framing

Explain own vs inherited properties, then compare Object.hasOwn, Object.keys, for...in, and Reflect.ownKeys.

Revision Notes

Property ownership is essential for safe iteration, merging, and validation.

Key Takeaways

Object key handling is small until it becomes a security or data correctness bug. Be explicit.

Follow-Up Questions

  1. What is an own property?
  2. What does Object.hasOwn check?
  3. Why not call obj.hasOwnProperty directly?
  4. What does Object.keys return?
  5. What does for...in include?
  6. How do symbol keys affect iteration?
  7. What does Reflect.ownKeys return?
  8. When should Map be used?
  9. Why validate untrusted keys?
  10. How does this relate to prototype pollution?

How I Would Answer This In A Real Interview

I would say property lookup can include prototypes, but data processing usually wants own properties. I would use Object.hasOwn and Object.keys for app data, Reflect.ownKeys for reflection, and Map or allowlists for arbitrary external keys.