JavaScript object detection: dot syntax versus 'in' keyword

Solution 1:

  • if(object.property)

    will fail in cases it is not set (which is what you want), and in cases it has been set to some falsey value, e.g. undefined, null, 0 etc (which is not what you want).

    var object = {property: 0};
    if(object.isNotSet) { ... } // will not run
    if(object.property) { ... } // will not run
    
  • if('property' in object)

    is slightly better, since it will actually return whether the object really has the property, not just by looking at its value.

    var object = {property: 0};
    if('property' in object) { ... } // will run
    if('toString' in object) { ... } // will also run; from prototype
    
  • if(object.hasOwnProperty('property'))

    is even better, since it will allow you to distinguish between instance properties and prototype properties.

    var object = {property: 0};
    if(object.hasOwnProperty('property')) { ... } // will run
    if(object.hasOwnProperty('toString')) { ... } // will not run
    

I would say performance is not that big of an issue here, unless you're checking thousands of time a second but in that case you should consider another code structure. All of these functions/syntaxes are supported by recent browsers, hasOwnProperty has been around for a long time, too.


Edit: You can also make a general function to check for existence of a property by passing anything (even things that are not objects) as an object like this:

function has(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}

Now this works:

has(window, 'setTimeout'); // true

even if window.hasOwnProperty === undefined (which is the case in IE version 8 or lower).

Solution 2:

It really depends what you want to achieve. Are you talking about host objects (such as window and DOM nodes)? If so, the safest check is typeof, which works for all host objects I know of:

 if (typeof object.property != "undefined") { ... }

Notes:

  • Avoid object.hasOwnProperty() for host objects, because host objects are not obliged to inherit from Object.prototype and therefore may not have a hasOwnProperty() method (and indeed in IE < 9, they generally do not).
  • A simple Boolean coercion (e.g. if (object.property) { ... }) is a poor test of the existence of a property, since it will give false negatives for falsy values. For example, for an empty textarea, if (textarea.selectionStart) { ... } will not execute the block even though the property exists. Also, some host object properties throw an error in older versions of IE when attempting to coerce to a Boolean (e.g. var xhr = new ActiveXObject("Microsoft.XMLHTTP"); if (xhr.responseXML) { ... }).
  • The in operator is a better test of the existence of a property, but there are once again no guarantees about support for it in host objects.
  • I recommend against considering performance for this kind of task. Choose the safest option for your project and only optimize later. There will almost certainly be much better candidates for optimization than property existence checks.

For more background on this, I recommend this excellent article by Peter Michaux.

Solution 3:

Definitely if ('property' in object) is the right way to go. That actually tests if the property is in the object (or in its prototype chain, more on that below).

if (object.property) on the other hand, will coerce 'property' into a truth/flase value. If the property is unset, it will return "undefined", which will be coerced into false, and appear to work. But this will also fail for a number of other set values of properties. javascript is notoriously inconsistent in what it treats as truthy and falsy.

Finally, like I said above, 'property' in 'object' will return true if it's in anywhere in the prototype chain. If you want to test that's on the object itself, and not somewhere higher up in the chain, you use the hasOwnProperty method like so:

if (object.hasOwnProperty('property')) ...