To check if a key exists in javascript, you have a few options:
Each method behaves slightly differently, so let’s do some examples of each.
Compare the key’s value to undefined
If you try to access a key that does not exist on a javascript object, the returned value will be undefined
1. Let’s see that in code:
const car = { make: "toyota", model: "camry" };
car.make; // "toyota"
car.year; // undefined
In other words, if you access an object key and receive undefined
back, that key was probably2 not present on the object.
if (car.year === undefined) {
console.log("year is not present");
} else {
// go ahead and use the year
}
If you have nested keys, however, you might run into issues:
const car = { make: "toyota", model: "camry" };
// This will result in an exception
if (car.details.mpg === undefined) {
console.log("MPG not present");
}
// Uncaught TypeError: Cannot read properties of undefined
The TypeError in the example above is because the car
object didn’t contain details
. So car.details
returned undefined, and you can’t do undefined.mpg
. To prevent this issue with nested objects, use optional chaining ?.
.
Use optional chaining for nested keys
Continuing the car example above, let’s say you’re not even sure you have the car object itself. You can use javascript’s optional chaining operator (?.
) to protect yourself.
const car = { make: "toyota", model: "camry" };
// This won't blow up
if (car?.details?.mpg === undefined){
console.log("MPG not present");
}
// "MPG not present"
// You can chain as far as you like
if (car?.details?.dimensions?.length?.inches) {
// this is safe from errors, but I'd probably
// ask questions in code review if I saw this
}
Optional chaining will account for both null
and undefined
values in the chain of object keys, so it should keep you fairly safe.
Object.hasOwnProperty
The hasOwnProperty
method was written for exactly this use case.
const car = { make: "toyota", model: "camry" };
car.hasOwnProperty("make"); // true
car.hasOwnProperty("year"); // false
Additionally, hasOwnProperty will ensure the property truly belongs to this specific object, and isn’t something it inherited. Here’s an example:
const car = { make: "toyota", model: "camry" };
// All JS objects inherit the .toString() method
// But it is not specific to our car object
car.hasOwnProperty("toString");
// false
Use the Javascript in
operator
Javascript’s in
operator is not that widely-used in my experience, but it’s a nice way to test if a key exists in an object. Importantly, the in
operator will return true for inherited properties, unlike hasOwnProperty
above.
const car = { make: "toyota", model: "camry" };
"make" in car; // true
"year" in car; // false
// "in" will find inherited properties from the prototype chain
"toString" in car; // true
// If you need to be *sure* it's local to this object, use hasOwnProperty
car.hasOwnProperty("toString"); // false
It is a bit unusual to see this syntax structure in Javascript, which is probably why in
isn’t too widely-used, but if you’re coming from Python it feels downright natural.
Helpful Links
- Javascript optional chaining – Moz Docs
Notes
- Unlike golang, which will give you the zero-value for that value’s type โฉ๏ธ
- I say probably because someone could deliberately set a value as
undefined
, but that would be very unusual as it violates the principal of least surprise. To indicate blank data, you would typically seenull
instead of `undefined`. โฉ๏ธ
Peter Kulek says
find object
let x = car && car.details && car.details.mpg ? car.details.mpg : {}
or put this in an isEmpty Function and check for any type of empty
if(isEmpty(car.details.mpg) {
do something
}
let isEmpty = exports.isEmpty = function(str) { // check if string is null or empty usually missing parameter
if ( str == undefined ) {
return true;
} else if ( str == null ) {
return true;
} else if (typeof str == ‘string’ ){
return typeof str == ‘string’ && !str.trim() || str == ‘undefined’ || str == ‘null’ || str === ‘[]’|| str === ‘{}’;
} else if (Array.isArray(str) ) {
return str.length == 0;
} else if ( typeof str == ‘object’ ) {
return Object.keys(str).length == 0;
} else {
return str == null || str == undefined;
}
}