New Best Practice
Sign In

Consider Object.prototype.hasOwnProperty() for Prop Checking

Wednesday, August 19, 2020

In most instances the Object.prototype.hasOwnProperty() method is the preferred strategy for determining if a property exists in an object with one exception.

Let's look at the two common strategies for property checking in JavaScript:

  1. The in operator
  2. The Object.prototype.hasOwnProperty() method

The in Operator

JavaScript's in operator returns a boolean indicating if the property exists in an object. Let's look at an example.

const Resorts = function () {
  this.Telluride = 4425;
  this.Vail = 3450;
}

// Brian's object of Resorts
const brianResorts = new Resorts();
brianResorts.Breckenridge = 3398;

// Jesse's object of Resorts
const jesseResorts = new Resorts();

const breckInBrianResorts = 'Breckenridge' in brianResorts;  // true
const breckInJesseResorts = 'Breckenridge' in jesseResorts;  // false

Let's break this down:

  • We defined a new Resorts function that represents the vertical feet of ski resorts.
  • Then, we created a new brianResorts object from the Resorts with its own properties.
  • Brian loves Breckenridge, so we include a new Breckenridge property in the brianResorts object.
  • Then, we created a new jesseResorts object from the Resorts with its own properties.
  • Jesse's not a fan of Breck, but like Brian, is a fan of Telluride and Vail.
  • The breckInBrianResorts value is true because the 'Breckenridge' property exists in the brianResorts object.
  • The breckInJesseResorts value is false because the 'Breckenridge' property not not exist in the jesseResorts object.

There is a potential foot gun when using the in operator; the in operator checks a given object and the object's prototype chain for the property.

Let's expand on our previous example.

const Resorts = function () {
  this.Telluride = 4425;
  this.Vail = 3450;
}

// Brian's object of Resorts
const brianResorts = new Resorts();

// Jesse's object of Resorts
const jesseResorts = new Resorts();

// modify function prototype
Resorts.prototype.Breckenridge = 3398;

const breckInBrianResorts = 'Breckenridge' in brianResorts; // true
const breckInJesseResorts = 'Breckenridge' in jesseResorts; // true

In the example above, we are modifying the function's prototype to add an additional property. Because we are using the in operator, both breckInBrianResorts and breckInJesseResorts are true since they inherit from the prototype.

As we learned earlier, Jesse is not a fan of Breck, so this is a potential problem.

Object.prototype.hasOwnProperty()

The Object.prototype.hasOwnProperty() determines if an object has the specified property, and does not check if the object has inherited the specified property via the object's prototype chain.

Let's take the previous example where we modified the function's prototype, and instead of using the in operator, let's use the object's hasOwnProperty() method.

const Resorts = function () {
  this.Telluride = 4425;
  this.JHMR = 4139;
  this.Vail = 3450;
}

// Brian's object of Resorts
const brianResorts = new Resorts();

// Jesse's object of Resorts
const jesseResorts = new Resorts();

// modify function prototype
Resorts.prototype.Breckenridge = 3398;

const breckInBrianResorts = brianResorts.hasOwnProperty('Breckenridge'); // false
const breckInJesseResorts = jesseResorts.hasOwnProperty('Breckenridge'); // false

The result is that both breckInBrianResorts and breckInJesseResorts are false. This is because both objects do not have a Breckenridge property, the property only exists in their prototype chain.

Finally, let's remove the Breckenridge property from the Resorts prototype and instead go back to the first example above and only add the property to the brianResorts object.

const Resorts = function () {
  this.Telluride = 4425;
  this.JHMR = 4139;
  this.Vail = 3450;
}

// Brian's object of Resorts
const brianResorts = new Resorts();
brianResorts.Breckenridge = 3398;

// Jesse's object of Resorts
const jesseResorts = new Resorts();

const breckInBrianResorts = brianResorts.hasOwnProperty('Breckenridge'); // true
const breckInJesseResorts = jesseResorts.hasOwnProperty('Breckenridge'); // false

As expected, the Breckenridge property now only exists in the brianResorts object.

Code Examples

const o = {
  first: 1,
  second: 2,
  third: 3
};
const exists = 'first' in o;

avoid: the in operator unless you need to check for a property existence in the object and its prototype chain

const o = {
  first: 1,
  second: 2,
  third: 3
};
const exists = o.hasOwnProperty('first');

do: use the Object.prototype.hasOwnProperty() to check for a property existence in an object

Instructions

  • Do:

    use the Object.prototype.hasOwnProperty() method for checking if a property exists in an object

  • Do:

    use the in operator for checking if a property exists in an object and its prototype chain

  • Avoid:

    the in operator for checking if a property exists in an object

Rules

Brian Love

Brian is a software engineer and Google Developer Expert in Web Technologies and Angular with a passion for learning, writing, speaking, teaching and mentoring. He regularly speaks at conferences and meetups around the country, and co-authored "Why Angular for the Enterprise" for O'Reilly. When not coding, Brian enjoys skiing, hiking, and being in the outdoors. Brian recently launched lookout.dev where you can find best practices and expert advice on topics ranging from TypeScript, Angular, React, Node.js and more.

Google Developers Expert

Discussions are healthy ❤️