Last updated: Mar 1, 2024
Reading timeยท8 min
in
Operatorin
OperatorUse the in
operator to check if a key exists in an object, e.g.
"key" in myObject
.
The in
operator will return true
if the key is present in the object,
otherwise false
is returned.
const person = { name: 'Bobby Hadz', }; console.log('name' in person); // ๐๏ธ true console.log('age' in person); // ๐๏ธ false if ('name' in person) { // ๐๏ธ this runs console.log('key is in contained in object'); }
The syntax used with the
in operator
is: string
in object
.
If you need to check if a key doesn't exist in an object, wrap the expression in parentheses.
const person = { name: 'Bobby Hadz', }; console.log(!('age' in person)); // ๐๏ธ true console.log(!('name' in person)); // ๐๏ธ false if (!('age' in person)) { // ๐๏ธ this runs console.log('key is not in object'); }
Wrapping the expression in parentheses allows us to evaluate it as a whole.
Alternatively, you can use the optional chaining (?.) operator.
If the key exists in the object, the optional chaining operator will return the
key's value, otherwise, it returns undefined
.
const person = { name: 'Bobby Hadz', }; console.log(person?.name); // ๐๏ธ Bobby Hadz console.log(person?.age); // ๐๏ธ undefined if (person?.name !== undefined) { // the key exists on the object }
We used the
optional chaining (?.) operator to check
if the name
and age
keys exist in the object.
The name
key exists in the object, so person?.name
evaluates to
Bobby Hadz
. The age
key doesn't, so the optional chaining operator returns
undefined
.
undefined
values in the object.const person = { name: undefined, }; console.log(person?.name); // ๐๏ธ undefined if (person?.name !== undefined) { // the `name` key exists, but this never runs }
The name
key exists in the object, but the condition in our if
statement
does not account for the case where the key is set to undefined
.
undefined
value present.You can also use the optional chaining operator to check if an object has a nested property.
const obj = {a: {b: 'hello'}}; const value = obj?.a?.b; console.log(value); // ๐๏ธ hello if (value !== undefined) { // if this block runs // ๐๏ธ property exists on the object }
If the specified property exists, its value is returned.
If the object's property doesn't exist the optional chaining ?.
operator
returns undefined
.
const obj = {}; const value = obj?.a?.b?.c; console.log(value); // ๐๏ธ undefined if (value !== undefined) { // if this block runs // ๐๏ธ property exists on the object }
We used the ?.
operator to access a nested property that doesn't exist on the
object.
When the ?.
operator tries to access the a
property, it gets an undefined
value and short-circuits returning undefined
.
Alternatively, you can use the Object.hasOwn()
method.
The Object.hasOwn
method returns true
if the key exists in the object,
otherwise, false
is returned.
const person = { name: 'Bobby Hadz', }; console.log(Object.hasOwn(person, 'name')); // ๐๏ธ true console.log(Object.hasOwn(person, 'age')); // ๐๏ธ false if (Object.hasOwn(person, 'name')) { // ๐๏ธ this runs console.log('key exists in the object'); }
The
Object.hasOwn
method returns true
if the specified property exists in the object.
If the property is inherited or doesn't exist, the method returns false
.
The difference between the Object.hasOwn()
method and the in
operator is
that the in
operator checks for the key in the object and its prototype chain,
whereas the Object.hasOwn()
method only checks for the existence of the key
directly on the object.
Alternatively, you can use the Object.keys()
method.
const person = { name: 'Bobby Hadz', age: 30, }; const keys = Object.keys(person); if (keys.includes('age')) { // ๐๏ธ this runs console.log('The key exists in the object'); } else { console.log('The key does NOT exist in the object'); } console.log(keys.includes('name')); // ๐๏ธ true console.log(keys.includes('another')); // ๐๏ธ false
The Object.keys method returns an array of the object's keys.
const person = { name: 'Bobby Hadz', age: 30, }; const keys = Object.keys(person); console.log(keys); // ๐๏ธ [ 'name', 'age' ] console.log(keys.includes('name')); // ๐๏ธ true console.log(keys.includes('another')); // ๐๏ธ false
Once we have an array of the object's keys, we can use the Array.includes()
method to check if the key exists in the object.
The Array.includes()
method returns true
if the supplied value is contained in the array and
false
otherwise.
Alternatively, you can use the Array.some()
method.
const person = { name: 'Bobby Hadz', age: 30, }; const keys = Object.keys(person); const keyExists = keys.some(key => { return key === 'age'; }); if (keyExists) { // ๐๏ธ this runs console.log('The key exists in the object'); } else { console.log('The key does NOT exist in the object'); }
The function we passed to the Array.some() method gets called with each element in the array of keys.
some()
method returns true
, otherwise, false
is returned.On each iteration, we check if the current key is equal to age
and return the
result.
const keyExists = keys.some(key => { return key === 'age'; });
The some()
function will return true
if the key is contained in the object
and false
otherwise.
You only have to iterate over the array with some()
if you need to check for a
more complex condition.
For example, you can check if a partial key exists in an object.
const person = { name: 'Bobby Hadz', age: 30, }; const keys = Object.keys(person); const keyExists = keys.some(key => { return key.includes('ag'); }); if (keyExists) { // ๐๏ธ this runs console.log('The partial key exists in the object'); } else { console.log('The partial key does NOT exist in the object'); }
The some()
function will return true
if any of the keys in the object
contains ag
.
Similarly, you can use this approach to check if a key exists in an object in a case-insensitive manner.
const person = { NAME: 'Bobby Hadz', AGE: 30, }; const keys = Object.keys(person); const keyExists = keys.some(key => { const str = 'age'; return key.toLowerCase() === str.toLowerCase(); }); if (keyExists) { // ๐๏ธ this runs console.log('The key exists in the object'); } else { console.log('The key does NOT exist in the object'); }
We used the some()
method to iterate over the array of keys.
On each iteration, we convert the key and the string to lowercase to perform a case-insensitive comparison.
You can use the nullish coalescing (??) operator to return a default value if a key doesn't exist.
const person = { name: 'Bobby Hadz', age: 30, }; const result = person.country ?? 'Example'; console.log(result); // ๐๏ธ Example
If the value to the left of the
nullish coalescing operator (??) is
equal to null
or undefined
, the value to the right is returned, otherwise,
the value to the left of the operator is returned.
If accessing the key returns undefined
, the value to the right is returned.
If you use lodash
, you can also use the lodash.get()
method to check if a
key exists in an object.
If you need to install lodash
, run the following command from your terminal.
# ๐๏ธ if you need to initialize a package.json file npm init -y npm install lodash # ๐๏ธ only if you use TypeScript npm install --save-dev @types/lodash
Now you can import and use the lodash.get()
and lodash.has()
methods.
import _ from 'lodash'; const person = { name: 'Bobby Hadz', address: { country: 'Example', }, a: [{b: {c: 3}}], }; console.log(_.has(person, 'name')); // ๐๏ธ true console.log(_.has(person, 'address.country')); // ๐๏ธ true console.log(_.has(person, 'a[0].b.c')); // ๐๏ธ true console.log(_.get(person, 'name')); // ๐๏ธ Bobby Hadz console.log(_.get(person, 'address.country')); // ๐๏ธ Example console.log(_.get(person, 'a[0].b.c')); // ๐๏ธ 3
The lodash.has() method checks if a path is a direct property of an object.
Notice that we can check for nested properties and can also access array elements in the path.
The lodash.get() method gets the value at the specified path.
You can also use the logical AND (&&) operator to check if an object has a nested property.
const obj = {}; if ( obj.a !== undefined && obj.a.b !== undefined && obj.a.b.c !== undefined ) { // if this block runs // ๐๏ธ the a.b.c property exists on the object }
We manually check for the existence of a nested property.
We used the logical AND &&
operator, so the conditions in the if
statement
get checked from left to right, one by one.
If any of the conditions evaluates to false
, the if
block won't run.
undefined
. You might see examples online that use only the logical AND &&
operator, however, this approach is error-prone.The following example checks if the value of an object's property is truthy.
Truthy values in JavaScript are all values that are not falsy. Falsy values are:
false
, 0
, ""
, null
, undefined
, NaN
.
Don't write code like this:
// โ๏ธ error-prone code const obj = {a: {b: {c: 0}}}; if (obj && obj.a && obj.a.b && obj.a.b.c) { // ๐๏ธ This never runs // even though the `c` property exists }
We check if a property of an object is truthy
, which isn't enough for us to
determine whether the property exists.
The a.b.c
property is set to 0
, which is a falsy
value, so even though the
property exists, the if
block never runs because the condition isn't met.
You can use the typeof
operator to check if an object contains a function.
The typeof
operator returns a string that indicates the type of the value. For
functions, the operator returns a string containing the word function.
const obj = { sum: (a, b) => { return a + b; }, }; if (typeof obj.sum === 'function') { // ๐๏ธ this runs console.log('โ the sum property points to a function'); } else { console.log( "โ๏ธ the sum property DOESN'T point to a function", ); } console.log(typeof obj.sum); // ๐๏ธ "function" console.log(typeof obj.doesNotExist); // ๐๏ธ "undefined"
We used the typeof operator to
check if the sum
property of the object points to a function.
typeof
operator returns a string containing the type of the value.If the equality check in our if
statement passes, the property on the object
points to a function.
Here are some more examples of using the typeof
operator.
console.log(typeof {}); // ๐๏ธ "object" console.log(typeof []); // ๐๏ธ "object" console.log(typeof null); // ๐๏ธ "object" console.log(typeof (() => {})); // ๐๏ธ "function" console.log(typeof ''); // ๐๏ธ "string" console.log(typeof 0); // ๐๏ธ "number" console.log(typeof NaN); // ๐๏ธ "number" console.log(typeof undefined); // ๐๏ธ "undefined"
The typeof
operator returns "function"
for both arrow and named functions.
console.log(typeof (() => {})); // ๐๏ธ function console.log(typeof function () {}); // ๐๏ธ function
Technically, the type of a class is also a function.
console.log(typeof class A {}); // ๐๏ธ function
Classes are just syntactic sugar for functions in JavaScript.
However, we can't have a class as a property in an object, so our solution works as expected.