Q147: Object.hasOwn, Enumeration and Key Safety
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
- What is an own property?
- What does Object.hasOwn check?
- Why not call obj.hasOwnProperty directly?
- What does Object.keys return?
- What does for...in include?
- How do symbol keys affect iteration?
- What does Reflect.ownKeys return?
- When should Map be used?
- Why validate untrusted keys?
- 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.