Object.hasOwn() vs Object.prototype.hasOwnProperty()
Asked Answered
V

1

33

The new method Object.hasOwn() returns a boolean indicating whether the specified object has the indicated property as its own property but so does Object.prototype.hasOwnProperty(), what is the difference between them and what is the benefit of using one over the other?

Viticulture answered 13/10, 2021 at 19:55 Comment(0)
V
61

Using Object.hasOwn() as a replacement for Object.hasOwnProperty()

Object.hasOwn() is intended as a replacement for Object.hasOwnProperty() and is a new method available to use (yet still not fully supported by all browsers like safari yet but soon will be)

Object.hasOwn() is a static method which returns true if the specified object has the specified property as its own property. If the property is inherited, or does not exist, the method returns false.

const person = { name: 'John' };
console.log(Object.hasOwn(person, 'name'));// true
console.log(Object.hasOwn(person, 'age'));// false

console.log(person.hasOwnProperty('name'));// true
console.log(person.hasOwnProperty('age'));// false

const person2 = Object.create({gender: 'male'});
console.log(Object.hasOwn(person2, 'gender')); // false
console.log(person.hasOwnProperty('gender')); //false
 
// gender is not an own property of person, it exist on the person2 prototype

So, after looking at both Object.hasOwn() and Object.hasOwnProperty() in action, they seem quite the same.. So why should we use Object.hasOwn() over the Object.hasOwnProperty()?

It is recommended to this method use over the Object.hasOwnProperty() because it also works for objects created by using Object.create(null) and for objects that have overridden the inherited hasOwnProperty() method. Although it's possible to solve these kind of problems by calling Object.prototype.hasOwnProperty.call(<object reference>, <property name>) on an external object, Object.hasOwn() overcome these problems, hence is preferred (see examples below)

let person = {
  hasOwnProperty: function() {
    return false;
  },
  age: 35
};
 
console.log(Object.hasOwn(person, 'age')); // true
console.log(person.hasOwnProperty('age')); // false

let person = Object.create(null);
person.age = 35;
if (Object.hasOwn(person, 'age')) {
  console.log(person.age); // true - works regardless of how the object was created
}

if (person.hasOwnProperty('age')){ // throws error - person.hasOwnProperty is not a function
   console.log('hasOwnProperty' + person.age);
}

More about Object.hasOwn can be found here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn

Browser compatibility - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility

Viticulture answered 13/10, 2021 at 19:56 Comment(4)
Nice answer. Just adding a link to the original proposal for people (like me) who want to see even more details.Adverb
why does "console.log(Object.hasOwn(person2, 'gender'))" return false? person2 does have the property if you inspect person2.gender? It wasn't created with troublesome "Object.create(null)" so curious why it doesn't return true.Racism
Because Gender is created not on the person2 object, but on it's prototype.Viticulture
Great answer, thanks. Adding that hasOwn() needs node16... if you have node-dependent 'stuff'. E.g., Postman Monitors' node version is not yet up to this version, so any Monitor test runs will fail, even though hasOwn() works locally. (EDIT: Thinking it's their node, since we updated node in Newman to work around this, but I digress...). So that's something to think about when choosing hasOwn(). Cheers.Deltoro

© 2022 - 2024 — McMap. All rights reserved.