Hint
for...in, Object.keys, Object.values, Object.entries β differ in own vs inherited, enumerable vs all
Each enumeration method has different behavior around own properties, inherited properties, and enumerability:
const parent = { inherited: true };
const obj = Object.create(parent); // obj's prototype is parent
obj.a = 1;
obj.b = 2;
Object.defineProperty(obj, 'hidden', { value: 3, enumerable: false });
// for...in β own + inherited, enumerable only
for (const k in obj) console.log(k); // 'a', 'b', 'inherited'
// Object.keys β own properties, enumerable only β most common
Object.keys(obj); // ['a', 'b']
// Object.values β own, enumerable, values
Object.values(obj); // [1, 2]
// Object.entries β own, enumerable, [key, value] pairs
Object.entries(obj); // [['a', 1], ['b', 2]]
// Object.getOwnPropertyNames β own, ALL (including non-enumerable)
Object.getOwnPropertyNames(obj); // ['a', 'b', 'hidden']
// Check if own property
obj.hasOwnProperty('a'); // true
obj.hasOwnProperty('inherited'); // false
Object.hasOwn(obj, 'a'); // ES2022 β preferred over hasOwnProperty