Check if an Object is Empty in JavaScript

By James L.

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.