I'm usually using this condition to check if a value of data is Object or not:
// function A
export const isObject = item => {
return item && item.constructor === Object;
};
since it is easier to understand, but my friend usually using this function to check data with the same condition as above isObject(value) {}
:
// function B
export function isObject(value) {
return typeof value === "object" && !Array.isArray(value) && value !== null;
}
we got confused when there is a conflict when we want to merge to latest branch, so here is the question, Between function A & B which one is better to cover most case regarding object data?
, Can you explain it too so I have a better knowledge about it.
CodePudding user response:
Assuming that you want to identify plain objects that inherit from Object.prototype
, and aren't subclasses of something else:
The first approach could be fooled because the .constructor
property doesn't necessarily refer to the constructor function used to create the function - an object could assign something else to that property.
const isObject = item => {
return item && item.constructor === Object;
};
const a = [];
console.log(a.constructor == Array);
a.constructor = Object;
console.log(a.constructor === Object);
console.log(isObject(a));
The second approach could be fooled because there are other sorts of things than arrays that inherit from Object.prototype
that aren't plain objects nor arrays - like HTMLElements and many, many other things.
function isObject(value) {
return typeof value === "object" && !Array.isArray(value) && value !== null;
}
console.log(isObject(document.body));
console.log(isObject(new Proxy({}, {})));
So I prefer Object.getPrototypeOf
, with which you can be quite confident that the value's immediate internal prototype is Object.prototype
, and that it's nothing else special.
const isObject = item => Object.getPrototypeOf(item) === Object.prototype;
console.log(isObject([]));
console.log(isObject({}));
console.log(isObject(document));
It could fail if Object.getPrototypeOf
is overwritten, of course - but if you're at that point, pretty much nothing is trustworthy anyway.
Note that many things inherit from Object.prototype
which will give true
for this, such as Number.prototype
- if you want to exclude those kinds, you could check if a .constructor
property exists.