I have a created a merging library that merges objects recursively. Sometimes in the middle there would be an object that is actually a special class (like the Timestamp of Firestore).
In my merging function I check if something is an object or not like so:
function isObject (payload) {
const getType = Object.prototype.toString.call(payload).slice(8, -1)
return getType === 'Object'
}
However, with this check some special classes with special prototypes are still considered to be regular JavaScript objects.
My problem:
The object will loose its special class prototype because I only go through the non-prototype values to recursively merge.
My question:
How can I change the function above to not only check if it's a JavaScript object, but also check if it's a regular JavaScript object?
Basically I only wanna return true
on isObject(obj)
if obj
is an object like so: {}
or with any props.
But once the prototype is different (and thus it's a special class), then I want to return false
on isObject(obj)
In addition to checking the prototype, you can check if its constructor
is Object
:
const isPlainObject = obj => obj.constructor === Object && Object.getPrototypeOf(obj) === Object.prototype;
const obj1 = { foo: 'bar' };
const obj2 = new Date();
const obj3 = [];
[obj1, obj2, obj3].forEach(obj => console.log(isPlainObject(obj)));
Note that using getPrototypeOf
and checking that it is ===
to Object.prototype
is more reliable than using toString
- toString
may return anything, after all.
If you're going to possibly pass something that's null or undefined to isPlainObject
, then of course include a check to see that the obj
is truthy before trying to access properties on it:
const isPlainObject = obj => obj && obj.constructor === Object && Object.getPrototypeOf(obj) === Object.prototype;
const obj1 = { foo: 'bar' };
const obj2 = new Date();
const obj3 = [];
[obj1, obj2, obj3].forEach(obj => console.log(isPlainObject(obj)));