The Art of Spotting Empty Objects — Javascript

Understanding Object Inspection and Empty Object Detection in JavaScript

How can we tell if a JavaScript object is empty? It’s a common challenge in development, and today we’ll explore various approaches to tackle this problem with different examples.

1. Unlocking the Power of `JSON.stringify` for Object Emptiness Testing

JSON.stringify is a handy method that serializes an object into its corresponding JSON format. For instance:

const obj = {};
console.log(JSON.stringify(obj) === '{}'); // true

Disadvantages: It may ignore undefined, function, and symbol values during serialization.

Example:


const obj = { a: undefined, b: function() {}, c: Symbol() };
console.log(JSON.stringify(obj) === '{}'); // true

2. Traversing Objects with `for in` and `hasOwnProperty`: A Reliable Approach to Empty Object Detection

  • for in: Iterates over all enumerable properties, including those from the object's prototype chain.
  • hasOwnProperty: Checks if a property belongs directly to the object, ignoring properties from the prototype chain.

Using `for in` to traverse an object and `hasOwnProperty` to ensure only its own properties are considered:

const obj = {};
Object.prototype.a = 1;

function isEmptyObj(obj) {
let flag = true;
for (let o in obj) {
if (obj.hasOwnProperty(o)) {
flag = false;
break;
}
}
return flag;
}

console.log(isEmptyObj(obj)); // true

Disadvantage: `for in` cannot traverse non-enumerable properties.

const obj = {
prop1: 'value1',
prop2: 'value2'
};

// Adding a non-enumerable property
Object.defineProperty(obj, 'nonEnumProp', {
value: 'non-enumerable',
enumerable: false
});

// Using for in loop to iterate over properties
for (let key in obj) {
console.log(key); // Outputs: prop1, prop2
}

// Checking if a property is enumerable
console.log(obj.propertyIsEnumerable('prop1')); // true
console.log(obj.propertyIsEnumerable('nonEnumProp')); // false

3. Object Keys Magic: How `Object.keys` Reveals Empty Objects in JavaScript

Utilizing `Object.keys` to obtain an array of enumerable properties of the object itself:

const obj = {};
Object.prototype.z = 1;
console.log(Object.keys(obj).length === 0); // true

Disadvantages: Similar to `for in`, `Object.keys` cannot traverse non-enumerable properties.

Testing with `Object.defineProperty`:

const obj = {};
Object.defineProperty(obj, 'z', { value: 1, enumerable: false });
console.log(obj.z); // 1
console.log(isEmptyObj(obj)); // true
console.log(Object.keys(obj).length === 0); // true

4. Beyond Enumeration: Uncovering Hidden Properties with `Object.getOwnPropertyNames`

Leveraging `Object.getOwnPropertyNames` to get an array of all property names, including non-enumerable properties:

const obj = {};
Object.defineProperty(obj, 'z', { value: 1, enumerable: false });
console.log(Object.getOwnPropertyNames(obj)); // [ 'z' ]

Disadvantages: Cannot obtain values as Symbol attributes.

Example with Symbol:

const z= Symbol();
const obj = { [z]: 1 };
console.log(Object.getOwnPropertyNames(obj).length === 0); // true

5. The Perfect Duo: Combining `Object.getOwnPropertyNames` and `Object.getOwnPropertySymbols` for Foolproof Empty Object Detection

Exploring the combination of `Object.getOwnPropertyNames` and `Object.getOwnPropertySymbols`:

const a = Symbol();
const obj1 = { [a]: 1 };

const obj2 = { b: 2 };

const obj3 = {};
Object.defineProperty(obj3, 'a', { value: 1, enumerable: false });

const obj4 = {};

function getLength(obj) {
return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)).length;
}

console.log(getLength(obj1) === 0); // false
console.log(getLength(obj2) === 0); // false
console.log(getLength(obj3) === 0); // false
console.log(getLength(obj4) === 0); // true

6. Reflect.ownKeys: The Most Perfect Method for Object Emptiness

Introducing Reflect.ownKeys, a comprehensive method returning an array of the object’s properties:

const a = Symbol();
const obj1 = { [a]: 1 };

const obj2 = { b: 2 };

const obj3 = {};

Object.defineProperty(obj3, 'a', { value: 1, enumerable: false });

const obj4 = {};

console.log(Reflect.ownKeys(obj1).length === 0); // false
console.log(Reflect.ownKeys(obj2).length === 0); // false
console.log(Reflect.ownKeys(obj3).length === 0); // false
console.log(Reflect.ownKeys(obj4).length === 0); // true

Summarize: Reflect.ownKeys stands out as the most perfect method for determining whether an object is empty.

In JavaScript, the Reflect object is a built-in object that provides methods for performing various operations on objects. It serves as a container for static methods that were once part of the Object object or related to meta-programming operations. The methods in the Reflect object are designed to be more consistent and expressive compared to equivalent operations that were previously scattered across different objects.

--

--

राहुल मिश्रा
राहुल मिश्रा

No responses yet