DEV Community

Evan Derby
Evan Derby

Posted on

Danger! Undefined ahead

Here's an interesting aspect of JavaScript that you may have run across before: if a key doesn't exist on an object, attempting to access that key will return undefined rather than throw an error:

let obj = {
  a : 1
}
obj['b'] // => undefined
obj['a'] // => 1
Enter fullscreen mode Exit fullscreen mode

We could use this aspect to our advantage to check if a key exists on an object:

const naive_object_has_key = (object, key) => object[key] !== undefined;
Enter fullscreen mode Exit fullscreen mode

But what if an operation somehow accidentally sets the value to undefined? Our naïve object_has_key method will tell us the key was never set.

The interesting bit is that any key which has been set on an object, even if the value is undefined, will be picked up by Object.keys:

let obj = {
  a : 1
}

obj.a = undefined;

Object.keys(obj) // => ['a']
Enter fullscreen mode Exit fullscreen mode

We can use this property to write a smarter object_has_key method.
This is useful if you are passing an object around to keep track of values or state, and need to know if the value that was assigned is truly undefined or is simply missing from the object:

const object_has_key = (object, key) => Object.keys(object).indexOf(key) != -1;

let data = {
  initial_value : 12
}

const transform_data = (object) => object['final_value'] = object['initial_value'] + 12;
Enter fullscreen mode Exit fullscreen mode

If we use our new helper method, we can know that a key was never assigned in the first place, even if an operation on that key mistakenly returned undefined:

object_has_key(data, 'final_value') // => false

const bad_transform_data = (object) => object['final_value'] = undefined;

bad_transform_data(data);

object_has_key(data, 'final_value') // => true
Enter fullscreen mode Exit fullscreen mode

If we try and check the value of data.final_value after it has been assigned, our helper function will return true.

transform_data(data);

object_has_key(data, 'final_value') // => true
Enter fullscreen mode Exit fullscreen mode

Thanks for reading!

Was this helpful or insightful for you? Maybe I'm totally forgetting about something or just completely wrong? Let me know in the comments!

Top comments (3)

Collapse
 
fly profile image
joon

lodash.com/docs/4.17.15#keys
lodash.com/docs/4.17.15#keysIn

Personally I won't be half surprised if lodash implements it in a similar fashion, but it does a fine job with an extra option for inherited properties :)

Collapse
 
karataev profile image
Eugene Karataev

I think hasOwnProperty method solves your case perfectly.
hasOwnProperty

Collapse
 
polyov_dev profile image
Evan Derby

if this were stack overflow, I would mark this as the accepted answer.