Question presented to candidate: "What does Object.hasOwn() actually check, how is it different from calling hasOwnProperty directly on an object, and why would you reach for hasOwn() instead in new code?"
What a strong answer should cover:
- Object.hasOwn(obj, prop) returns true only if prop exists directly on obj itself, not inherited via the prototype chain -- functionally equivalent to Object.prototype.hasOwnProperty.call(obj, prop).
- The problem hasOwn() solves: calling obj.hasOwnProperty(prop) directly assumes obj actually inherits a working hasOwnProperty from Object.prototype. An object created with Object.create(null) has no prototype at all, so obj.hasOwnProperty is not a function, and the call throws a TypeError.
- The same failure mode happens if an object has its own property literally named hasOwnProperty that shadows the inherited method with something that is not a function.
- Object.hasOwn() sidesteps both cases entirely because it is a static method -- it never relies on the target object having (or not having overridden) its own hasOwnProperty.
- It is distinct from the in operator, which returns true for inherited properties too, walking the whole prototype chain -- hasOwn() only ever reports own properties.
Clarifying questions expected:
- "Should I compare this against the in operator as well, or just against hasOwnProperty.call()?"
- "Is there a meaningful difference in behavior for array indices versus regular object keys?"
Code / implementation expected: Yes -- a runnable comparison including a null-prototype object and a shadowed hasOwnProperty property, both showing the real failure hasOwn() avoids.