Methods to determine if an Object has a given property


There are multiple ways to detect whether an Object has a property. You’d think it’d be as easy asmyObject.hasOwnProperty('prop');- but no, there are a few different ways with their own problems and gotchas. Let’s look at the few ways to check property existence, concepts that confuse JavaScript developers, prototype chain lookups and problems JavaScript might provide us.

⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯

Table of Contents

⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯

Double bang !! property lookup

We’ve all seen it, probably in something such as Modernizr for simple feature detection, the infamous!!amongst our JS. Important note before we begin this one, it doesn’t actually check if an Object has a property “as such”, it checks the_value_of the Object property. Which means if the property value is false, or the object property doesn’t even exist, they give the samefalsyresult - which can be really bad if you use it without knowing what it does and its limitations.

What does it mean?

The double-bang is a simple way to typecast something toBoolean. TheBooleanwill casttruefortruthy_values. Even things such asundefinedandnull(both falsy values,!!nullisfalsewhen cast toBoolean). The_absolute key_here is that it casts_values. I’ll say it again,values! This is irrelevant to the shape and size of your Object. We convert truthy and falsy values to Boolean.

Examples

An emptyArrayis an example of a_truthy_value:

var a = []; // []

What if we want to convert it to aBooleanthough? It’s truthy, so we should expecttrue:

var a = !![]; // true

nullis an example of a_falsy_value:

var a = null; // null

And the expected output offalse:

var a = !!null; // false

This means that we can use it when looking up our Objects!

var toddObject = {
  name: 'Todd',
  cool: false
};
!!toddObject.name // true (correct result as it's a truthy value)

This method also looks up the Object’sprototypechain to see if the property exists, which can cause unintended side effects if naming of properties is the same as a prototypes.

// Object.prototype.toString
!!toddObject.toString // true

// !!Array.prototype.forEach
!![]['forEach'] // true

Gotchas

Beware of using it for detecting your own Objects. We often create Objects and defaults such as this:

var toddObject = {
  name: 'Todd',
  favouriteDrink: null
};

If we’re using the double-bang to check if an Object property exists using this method, then it’s definitely a silly idea:

var toddObject = {
  name: 'Todd',
  favouriteDrink: null
};
if (!!toddObject.favouriteDrink) { // false
  // do something if it exists, I think...
}

That would be naive! The above code (to the new developer or non-double-banger) might say“If toddObject.favouriteDrink exists, do something”. But no, because (I’ll say it again…) this castsvalues, the value isnulland falsy - even though the property exists. It’s generally not a good idea in this case to use it for checking if a property exists incase it has a falsy value to begin with.

⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯

hasOwnProperty

We went as far as getting a native method for this, but it’s not 100% reliable for a few reasons. Let’s examine it first.

What does it mean?

UsingmyObject.hasOwnProperty('prop')is a great way of accessing the Object’s keys directly, which_does not_look into the Object’sprototype- hooray, this is great for specific use cases.hasOwnPropertyreturns a Boolean for us on whether a property exists.

Examples

var toddObject = {
  name: 'Todd',
  favouriteDrink: null
};
if (toddObject.hasOwnProperty('favouriteDrink')) { // true
  // do something if it exists, fo sho
}

But don’t be sold on this exact implementation… read below for best practice.

Gotchas

IE messes up thehasOwnPropertymethod completely as it’s painful withhostObjects (host objects don’t have the hasOwnProperty method).

JavaScript also decided not to protect the method’s name, so we can infact do this:

var toddObject = {
  hasOwnProperty: 'hello...'
};

This makes it hard to fully trust it. What we can do however is access theObject.prototypedirectly to guarantee anyhasOwnPropertycalls haven’t been tampered with or overridden.

Let’s bulletproof the process:

var toddObject = {
  name: 'Todd',
  favouriteDrink: null
};
if (Object.prototype.hasOwnProperty.call(toddObject, 'favouriteDrink')) { // true
  // do something if it exists, fo sho sho!
}

The secret sauce here is.call()to change the context ofhasOwnProperty(take that, IE) and ensure we’ve the exacthasOwnPropertywe want from theObject.prototype.

Obviously you’d want to wrap it inside a helper function or something to save writing out thatprototypeeach time:

function hasProp (obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}
if (hasProp(toddObject, 'favouriteDrink')) {}
⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯

‘prop’ in myObject

Theinoperator isn’t so widely used as the former methods, but is probably worth using after reading this. It also returns aBooleanmuch like!!myObject, but does not evaluate the value, it evaluates the existence of the property! This means if a property has a value offalse, we get a correct reading that the property does in fact exist.

var toddObject = {
  name: 'Todd',
  favouriteDrink: null,
  cool: false
};
'cool' in toddObject; // true

Theinoperator is probably your best friend for checking the existence of a property, it’s also pretty concise.

Gotchas

Theinoperator also looks up theprototype, which_may_cause unintended side effects:

// inherits Object.prototype.toString
'toString' in toddObject; // true

But we should know these property names and not create conflicts, right ;)

typeof

We can usetypeofas well.

What does it mean?

The standardtypeofoperator returns aString(not a very reliable one), and we can evaluate it against something, such as!== 'undefined'- which indicates it exists.

if (typeof toddObject.name !== 'undefined') {
  // do something
}

It looks a little ugly, as well as being quite long to write out if we were to make multiple checks using this method. Also,nullwould fall under this check unless using!= 'undefined'(single=) asnull == undefinedanyway.

Gotchas

Only use itif you know what you’re doingas it’s very unreliable for standard type checking.

⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯

Feature detection

I can’t recall exactly what was said, but someone (I think) once told me that some vendor once implemented a feature with a falsy value if it didn’t exist (though I’m not even certain that’s true, worth a mention though)… and as such theinoperator is best for these such cases:

// just an example, not the one somebody mentioned...
if ('draggable' in document.createElement('div')) {
  // do something if prop exists
}

(Source: https://toddmotto.com/methods-to-determine-if-an-object-has-a-given-property/#double-bang--property-lookup)

results matching ""

    No results matching ""