Check if an Object is Empty in JavaScript
In JavaScript, an object is a fundamental data type that allows us to store and organize multiple related data as key-value pairs.
There are several situations where we need to check if an object is empty in JavaScript, such as iterating over its properties or sending it as data in an AJAX request.
Additionally, checking if an object is empty can be useful when working with third-party APIs, where we might receive an empty object as a response and need to handle it appropriately.
JavaScript doesn’t have a built-in method to check if an object is empty. However, there are several ways to achieve this using other built-in methods.
Using Object.keys() method
The Object.keys()
method returns an array containing the keys of the specified object.
For example:
const person = {
name: "James Bond",
age: 37,
country: "United Kingdom"
};
console.log(Object.keys(person));
// Output: ['name', 'age', 'country']
Now we can use the length
property of the array to check if the returned array is empty or not. The length
property returns the number of elements in the array (number of keys in our case).
If it is equal to 0
, it indicates the object is empty. Otherwise, it signifies the object contains one or more properties and is not empty.
For example:
const person = {
name: "James Bond",
age: 37,
country: "United Kingdom"
};
const emptyObj = {};
console.log(Object.keys(person).length); // Output: 3
console.log(Object.keys(emptyObj).length); // Output: 0
Now with this knowledge, let’s create a function that checks if the object is empty.
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
const person = {
name: "James Bond",
age: 37,
country: "United Kingdom"
};
const emptyObj = {};
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
The isEmpty(obj)
function returns true
if the object is empty. Otherwise, it returns false
.
Validating data type
To check if an object is empty, it is important to first make sure it is actually an object. Just looking at the number of keys may not be enough.
We can use the typeof
operator to determine the data type of a given value. It returns a string that represents the type of the value.
function isEmpty(obj) {
if (typeof obj === 'object' && !Array.isArray(obj) && obj !== null) {
return Object.keys(obj).length === 0;
}
return "Invalid type";
}
const person = {
name: "James Bond",
age: 37
};
const emptyObj = {};
let myArray = [1, 2, 3];
let nullVar = null;
let undefinedVar;
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
console.log(isEmpty(myArray)); // OUtput: Invalid type
console.log(isEmpty(nullVar)); // Output: Invalid type
console.log(isEmpty(undefinedVar)); // Output: Invalid type
In the example above, we create a function isEmpty()
that takes an object as an argument and checks if the object is empty or not. The function returns true
if the object is empty, false
if it is not empty, and "Invalid type"
if the argument passed to the function is not an object.
The function first checks if the argument passed to it is an object using the typeof
operator. If the argument is an object, it then checks if it is not an array using the Array.isArray()
method and if it is not null
. If all these conditions are met, the function returns true
if the number of keys in the object is 0
(i.e. the object is empty) and false
otherwise. If any of these conditions are not met, the function returns "Invalid type"
.
In JavaScript, arrays are a specific type of object. The typeof
operator returns object
for arrays. So we have to check the type of the array using the Array.isArray()
method to ensure that the function isEmtpy()
correctly identifies arrays as invalid input and returns "Invalid type"
.
The typeof
operator returns object
for null
. This is often considered a historical quirk or even a mistake in the language’s design. This behavior dates back to the early days of JavaScript and has been preserved for backward compatibility reasons. That’s why we need to check if the object is not null
.
If you want to return null
for null variable and undefined
for undefined variables, we can modify the above code as follows:
function isEmpty(obj) {
// Return null if the variable is null
if (obj === null) {
return null;
}
// Return undefined if the variable is undefined
if (obj === undefined) {
return undefined;
}
// Return true if the object is an object and not an array
if (typeof obj === 'object' && !Array.isArray(obj)) {
return Object.keys(obj).length === 0;
}
// Return "Invalid type" otherwise
return "Invalid type";
}
const person = {
name: "James Bond",
age: 37
};
const emptyObj = {};
let myArray = [1, 2, 3];
let nullVar = null;
let undefinedVar;
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
console.log(isEmpty(myArray)); // OUtput: Invalid type
console.log(isEmpty(nullVar)); // Output: null
console.log(isEmpty(undefinedVar)); // Output: undefined
Can we use the ‘constructor’ property or ‘instanceof’ operator instead of the ‘typeof’ operator?
Using the constructor
property to check the data type of an object in JavaScript is a valid approach. However, this method relies on the accuracy of the constructor
property, which might not always be reliable. For example, if the objects have been created with custom constructors or if the prototype chain has been modified, this method might not work as expected.
Similarly, the instanceof
operator may not always work as expected with objects created with custom constructors.
In JavaScript, there is no single perfect way to check if a value is an object. Each method has its own limitations and it’s important to choose the right method based on your specific needs and requirements.
Using the typeof
operator in combination with other methods like Array.isArray()
is the most robust way to check if the value is an object. However, don’t forget to also check if the value is null
, as typeof null
returns object
.
Using for…in loop
The for…in
loop is used for iterating over the enumerable properties of an object. It allows us to loop through the keys (property names) of an object, giving us access to each key one at a time.
function isEmpty(obj) {
for (key in obj) {
return false;
}
return true;
}
const person = {
name: "James Bond",
age: 37
};
const emptyObj = {};
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
The isEmpty()
function takes an object as an argument and returns a boolean value.
Inside the for…in
loop, it immediately returns false
as soon as it encounters the first key in the object. This means that if the object has any properties, it assumes it is not empty and exits the function with false
.
If the loop completes without finding any keys, the function returns true
indicating the object is empty.
Validating data type
In JavaScript, arrays are a special type of object where the indices are the keys. The keys are automatically assigned as numeric values starting from 0
.
Therefore, we need to check the type of the array using the Array.isArray()
method to ensure that the function isEmpty()
correctly identifies arrays as invalid input and returns "Invalid type"
.
It is also important to handle null
and undefined
variables when checking the type of a variable.
function isEmpty(obj) {
// If 'obj' is array, return "Invalid type"
if (Array.isArray(obj)) {
return "Invalid type";
}
// If 'obj' is null, return null
if (obj === null) {
return null;
}
// If 'obj' is undefined, return undefined
if (obj === undefined) {
return undefined;
}
// If 'obj' has one key, return false
for (key in obj) {
return false;
}
// Otherwise return true
return true;
}
const person = {
name: "James Bond",
age: 37
};
const emptyObj = {};
let myArray = [1, 2, 3];
let nullVar = null;
let undefinedVar;
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
console.log(isEmpty(myArray)); // Output: Invalid type
console.log(isEmpty(nullVar)); // Output: null
console.log(isEmpty(undefinedVar)); // Output: undefined
Inherited properties and misleading empty object checks
I have found that most solutions found on the internet use the Object.hasOwnProperty()
method inside a for…in
loop to check if an object has any keys. However, this approach can be misleading.
If the object has only inherited properties, the Object.hasOwnProperty(key)
statement still evaluates to false
.
An object that only contains inherited properties is typically not considered empty because it still has properties, even though those properties are inherited from its prototype chain.
Let’s see an example:
function isEmpty(obj) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
const person = {
name: "James Bond",
age: 37
};
// Creating a new object 'car' with 'person' as its prototype (parent)
const car = Object.create(person);
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(car)); // Output: true
In the example above, we create an object person
with two properties: name
and age
. We also create an object car
using the Object.create()
method, with person
as its prototype. This means that the car
inherits the properties of the person
object.
Even though the car
object is not empty. It contains the properties inherited from the person
object, the isEmpty()
function returns true
. This is because the Object.create(key)
statement inside the if
block evaluates to false
, so the if
block doesn’t get executed.
Using JSON.stringify() method
In this method, we convert the object to a JSON
string using the JSON.stringify()
method and check if the resulting string is equal to "{}"
. If the object is empty, it returns "{}"
.
For example:
function isEmpty(obj) {
return JSON.stringify(obj) === "{}";
}
const person = {
name: "James Bond",
age: 37
};
const emptyObj = {};
let myArray = [1, 2, 3];
let nullVar = null;
let undefinedVar;
console.log(isEmpty(person)); // Output: false
console.log(isEmpty(emptyObj)); // Output: true
Limitations of JSON.stringify() method
Using JSON.stringify()
method to check if an object is empty can be a quick and easy solution, but it comes with lots of limitations.
(1) This method only works for objects that can be serialized to JSON
. Some values such as functions
, undefined
, and Symbol
are not valid JSON
values and are not included in the resulting JSON
string when an object is serialized. This means that an object containing only these types of values would be considered empty by this method, even though it has properties.
(2) This method only considers an object’s own enumerable properties. This means that non-enumerable properties and properties inherited from the object’s prototype chain are not included in the resulting JSON
string. As a result, an object that has non-enumerable or inherited properties but has no own enumerable properties would be considered empty by this method, even though it technically has properties.
(3) Stringifying the entire object to check for emptiness can be less efficient, especially for large objects, compared to methods that directly examine the object’s properties.