Hiprup

What is the difference between hasOwnProperty and the in operator?

Both check whether a property exists, but they look in different places.

  • in — true if the property exists on the object or anywhere up its prototype chain.

  • hasOwnProperty — true only for the object's own property, ignoring inherited ones.

Modern tip: Object.hasOwn(obj, key) is the safer replacement for obj.hasOwnProperty(key).

const parent = { inherited: true };
const child = Object.create(parent);
child.own = true;

// in — checks own + prototype chain
console.log('own' in child);       // true (own property)
console.log('inherited' in child); // true (inherited from parent)
console.log('toString' in child);  // true (from Object.prototype)

// hasOwnProperty — checks own only
console.log(child.hasOwnProperty('own'));       // true
console.log(child.hasOwnProperty('inherited')); // false
console.log(child.hasOwnProperty('toString'));  // false

// Object.hasOwn (modern, ES2022)
console.log(Object.hasOwn(child, 'own'));       // true
console.log(Object.hasOwn(child, 'inherited')); // false

// Why hasOwn is safer
const noProto = Object.create(null); // No prototype!
noProto.key = 'value';
// noProto.hasOwnProperty('key'); // TypeError! (no hasOwnProperty method)
Object.hasOwn(noProto, 'key');       // true (always works)

in finds 'inherited' on the prototype chain (true). hasOwnProperty only checks the object itself (false for inherited). Object.hasOwn is the modern safe alternative — works on objects without a prototype (Object.create(null)), where calling .hasOwnProperty would throw TypeError.

in = own + prototype, hasOwnProperty = own only. Object.hasOwn (ES2022) is the modern replacement — safer because it works on prototype-less objects.

The Object.create(null) edge case shows why hasOwn was introduced.

What is the difference between hasOwnProperty and the in operator? | Hiprup