'In' Operator Avoids False Falsies

I have encountered more than my share of javascript errors because I have made assumptions about the object I am working with, such as assuming that an object contains a property, and that I can call methods on that property:

1
2
> myObject.data[0]
TypeError: Cannot read property '0' of undefined

This line contains four assumptions, and therefore four places it can fail:

  1. myObject exists
  2. myObject contains a property called data
  3. data is an array
  4. data is non-empty

Presuming that if myObject does not exist means you have bigger problems, it is easy to fall into the trap of checking for the existence of a property by gating a conditional with it:

1
2
3
if(myObject.data) {
  //do something important with the data
}

This technique will work in development, but the voice of experience tells us that it will not work in production. The reason it will not work is that javascript has more falsy values than most languages. Falsy values include the number zero, empty strings, null, undefined, NaN, and of course, the boolean false. So, if it is possible myObject.data to contain derived information, you have signed up to troubleshoot some unexpected behaviour.

Fortunately, javascript has provided a failsafe way to check the existence of a property, regardless of the data it contains. The in operator checks if the key exists in the object’s hash table, and doesn’t care if it is a prototype or singleton property.

1
2
3
4
5
6
7
8
9
10
11
> var myObject = {}
undefined
> 'data' in myObject
false

> myObject.data = ''
""
> 'data' in myObject
true
> myObject.data == true
false

('data' in myObject) returns false if the property is undefined. If the property is defined, it returns true even if data contains a falsy value.

Resources

The principles of object-oriented javascript