Question
After an AJAX request, my JavaScript application may sometimes receive an empty object such as:
const a = {};
How can I reliably check whether the object is empty?
Short Answer
By the end of this page, you will understand what an "empty object" means in JavaScript, how to test for it safely, and which approaches are most commonly used in real code. You will also see common mistakes, practical examples, and a small mini-project using data returned from an AJAX-style request.
Concept
In JavaScript, an object is considered empty when it has no own enumerable properties.
For example:
const user = {};
This object has no keys, so it is empty.
A common and reliable way to test this is:
Object.keys(user).length === 0
Object.keys(obj) returns an array of the object's own enumerable property names. If that array has length 0, the object has no such properties.
This matters because many APIs, AJAX requests, and configuration objects use objects to return data. Your program often needs to behave differently when:
- data exists
- data is missing
- the object is present but empty
For example, an API might return:
{}
instead of:
{ "name": "Ava" }
Knowing how to detect an empty object helps with:
- showing fallback UI
- skipping processing
- validating responses
- preventing runtime errors
One important detail: not every value that looks object-like should be treated the same. Arrays, null, and class instances are different cases. So in real programs, developers often combine an emptiness check with a type check.
Mental Model
Think of a JavaScript object as a backpack with labeled pockets.
const bag = {
phone: true,
keys: true
};
The property names (phone, keys) are the labeled pockets.
An empty object is like an empty backpack:
const emptyBag = {};
There are no labeled pockets inside.
So when you check:
Object.keys(emptyBag).length === 0
you are basically asking:
"How many labeled pockets does this backpack have?"
If the answer is 0, the backpack is empty.
Syntax and Examples
The most common syntax is:
Object.keys(obj).length === 0
Basic example
const a = {};
console.log(Object.keys(a).length === 0); // true
Explanation:
Object.keys(a)returns[][].lengthis0- so the result is
true
Example with data
const user = { name: "Maya" };
console.log(Object.keys(user).length === 0); // false
Explanation:
Object.keys(user)returns["name"]- its length is
1 - so the object is not empty
Safer helper function
In real projects, it is common to wrap the check in a function:
function isEmptyObject(value) {
return value !== null &&
typeof value === "object" &&
!Array.isArray(value) &&
Object.keys(value).length === 0;
}
console.log(isEmptyObject({})); // true
console.log(isEmptyObject({ id: 1 })); // false
console.log(isEmptyObject(null)); // false
console.log(isEmptyObject([])); // false
This helps avoid treating null or arrays as plain empty objects.
Older loop-based approach
function isEmptyObject(obj) {
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
return false;
}
}
return true;
}
This checks whether the object has any own properties. If it finds one, it returns false. Otherwise, it returns true.
Step by Step Execution
Consider this example:
const response = {};
if (Object.keys(response).length === 0) {
console.log("Empty object");
} else {
console.log("Has data");
}
Step by step:
-
responseis assigned an empty object:{} -
Object.keys(response)runs.Because
responsehas no own enumerable properties, the result is:[] -
.lengthis checked.[].length === 0This becomes:
0 === 0 -
The condition is
true, so JavaScript enters the first branch:console.log("Empty object"); -
Output:
Empty object
Now compare with:
const response = { status: "ok" };
Then:
Object.keys(response)becomes["status"].lengthbecomes11 === 0isfalse- the
elsebranch runs
Real World Use Cases
Checking for empty objects is common in many practical situations.
API and AJAX responses
const response = {};
if (Object.keys(response).length === 0) {
console.log("No data returned");
}
Useful when an endpoint returns an empty result instead of null or an error.
Form validation errors
Some apps store validation errors in an object:
const errors = {};
if (Object.keys(errors).length === 0) {
console.log("Form is valid");
}
If there are no keys, there are no validation messages.
Filter objects
An app may build a search filter object dynamically:
const filters = {};
if (Object.keys(filters).length === 0) {
console.log("No filters selected");
}
Configuration objects
const options = {};
if (Object.keys(options).length === 0) {
console.log("Using default settings");
}
State management
In frontend apps, an object may represent loaded data:
const cache = {};
if (Object.keys(cache).length === 0) {
console.log("Cache is empty");
}
Real Codebase Usage
In real codebases, developers usually do more than just check Object.keys(obj).length === 0.
Guard clauses
A guard clause exits early when data is empty:
function renderProfile(profile) {
if (Object.keys(profile).length === 0) {
return "No profile data available";
}
return `Hello, ${profile.name}`;
}
This keeps the rest of the function simpler.
Validation before processing
function processSettings(settings) {
if (!settings || Object.keys(settings).length === 0) {
throw new Error("Settings object is empty");
}
// continue processing
}
Defensive type checking
function isPlainEmptyObject(value) {
return value !== null &&
typeof value === "object" &&
!Array.isArray(value) &&
Object.keys(value).length === 0;
}
This avoids accidental matches with arrays.
Conditional rendering in frontend code
function showUserPanel(user) {
if (Object.keys(user).length === 0) {
return "Loading or no user found";
}
return user.name;
}
Error handling with remote data
function handleApiResponse(data) {
if (!data || Object.keys(data).length === 0) {
console.error("API returned no usable data");
return;
}
console.log("Process data here");
}
A common pattern is: validate first, then continue.
Common Mistakes
1. Comparing objects directly
This does not work:
const a = {};
console.log(a === {}); // false
Why?
Objects are compared by reference, not by content. These are two different object instances.
Avoid this by using:
Object.keys(a).length === 0
2. Forgetting about null
Broken example:
const value = null;
console.log(Object.keys(value).length === 0);
This throws an error because Object.keys expects an object-like value.
Safer version:
const value = null;
const isEmpty = value !== null && typeof value === "object" && Object.keys(value).length === 0;
3. Treating arrays like plain objects
console.log(Object.keys([]).length === 0); // true
This may be technically true for an empty array, but an array is not the same as a plain object.
If you only want plain objects:
!Array.isArray(value)
4. Ignoring inherited properties in for...in
Broken example:
function isEmpty(obj) {
for (const key in obj) {
return false;
}
return true;
}
This can be misleading because for...in also sees inherited enumerable properties.
Better:
function isEmpty(obj) {
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
return false;
}
}
return true;
}
5. Assuming all objects should be checked the same way
Some objects come from classes, libraries, or built-in types like Date or Map. A plain object emptiness check may not match your actual intent.
Always ask:
- Is this a plain object?
- Could it be
null? - Could it be an array?
- Do I care about own properties only?
Comparisons
Common ways to test emptiness
| Approach | Example | Good for | Notes |
|---|---|---|---|
Object.keys | Object.keys(obj).length === 0 | Most common plain-object checks | Clear and readable |
for...in with own check | loop + Object.hasOwn(obj, key) | Older environments or custom logic | More verbose |
| Direct comparison | obj === {} | Never for emptiness | Incorrect for object content |
JSON.stringify | JSON.stringify(obj) === "{}" | Rare quick checks | Slower and less clear |
Object.keys vs for...in
| Feature | Object.keys | for...in |
|---|---|---|
| Own properties only | Yes | No, not by default |
| Enumerable properties | Yes | Yes |
| Readability | High | Medium |
| Common modern usage | Very common | Less common for this task |
Plain object vs array
| Value | typeof result | Object.keys(...).length === 0 | Should it count as empty object? |
|---|---|---|---|
{} | "object" | true | Yes |
{ a: 1 } | "object" | false | No |
[] | "object" | true | Usually no |
null | "object" | Error if used directly | No |
Cheat Sheet
// Most common check
Object.keys(obj).length === 0
Safe plain-object check
function isEmptyObject(value) {
return value !== null &&
typeof value === "object" &&
!Array.isArray(value) &&
Object.keys(value).length === 0;
}
Rules to remember
- An empty object has no own enumerable properties.
obj === {}does not test emptiness.nullmust be checked beforeObject.keys.- Arrays are objects in JavaScript, but usually should not be treated as plain objects.
Object.keys(obj)returns an array of property names.
Useful patterns
if (Object.keys(data).length === 0) {
// handle empty object
}
if (!value || Object.keys(value).length === 0) {
// handle missing or empty data
}
Be careful: the second pattern also matches other falsy values such as null.
Avoid
obj === {}
JSON.stringify(obj) === "{}" // usually not the best choice
Alternative loop
function isEmptyObject(obj) {
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
return false;
}
}
return true;
}
FAQ
How do I check if a JavaScript object is empty?
Use:
Object.keys(obj).length === 0
This is the most common modern approach for plain objects.
Why does obj === {} return false?
Because objects are compared by reference, not by their contents. Two separate object literals are different objects.
Should I use Object.keys or for...in?
Usually Object.keys is simpler and clearer. Use for...in only if you need custom iteration logic.
Does this work for arrays?
Object.keys([]).length === 0 returns true for an empty array, but arrays are not plain objects. If you need to exclude arrays, add !Array.isArray(value).
What happens with null?
Object.keys(null) throws an error. Check for null first.
Is JSON.stringify(obj) === "{}" a good way to check?
It works in some simple cases, but it is less clear and usually not the preferred approach.
How do I check for an empty object from an API response safely?
Use a defensive helper:
function isEmptyObject(value) {
return value !== null &&
typeof value === "object" &&
!Array.isArray(value) &&
Object.keys(value).length === 0;
}
Mini Project
Description
Build a small response checker for API-style data. Sometimes a request returns a user object, and sometimes it returns an empty object. This project demonstrates how to detect that case safely and respond with a useful message.
Goal
Create a function that checks whether returned data is an empty plain object and prints the correct status message.
Requirements
- Create a helper function to detect an empty plain object.
- Test the helper with an empty object and a non-empty object.
- Exclude arrays and
nullfrom being treated as empty plain objects. - Print a different message for empty and non-empty responses.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.