I am looking for a quick check to determine if a value is an object {}
but not an array []
. I have written this:
function isPlainObject(input) {
return !Array.isArray(input) && typeof input === 'object';
}
Is there a shorter check I can use to determine this?
Or are there other possible data structures that still checkout as typeof
'object'
?
Example: Check Array Using Array. isArray() method is used to check if an object is an array. The Array. isArray() method returns true if an object is an array, otherwise returns false . Note: For an array, the typeof operator returns an object.
One type of object that is built-in to JavaScript is the array, and the typeof of an array is "object" : typeof [] === `object` // true . ECMAScript 5 introduced an Array. isArray() method to check for an array, since typeof will not be able to tell arrays from other objects.
Apparently there seems to be something wrong because the array is recognized as an object and seems to be no real difference between object and array. This because in javascript all derived data type is always a type object.
The isArray() method returns true if an object is an array, otherwise false .
It is not quicker, but more precise, with a check for falsy values, like null
, which is an object.
function isPlainObject(input) {
return input && !Array.isArray(input) && typeof input === 'object';
}
If you want to check if an object is a "plain" object, i.e. inherits directly from Object.prototype, then you should check for that.
E.g. the following first tests if value has Object anywhere on it's prototype chain (and hence will not throw an error for getPrototypeOf), then checks if its immediate [[prototype]]
is Object.prototype:
function isPlainObject(value) {
return value instanceof Object &&
Object.getPrototypeOf(value) == Object.prototype;
}
// Some tests
[[1,2], // Array
{}, // Plain object
null, // null
document.createElement('div'), // host object
function(){}, // function object
console // host objet
].forEach(function(value) {
console.log(value + ': ' + isPlainObject(value));
});
If you want to test that the input is some extended object but not a Function, etc. that is much less efficient, e.g. test against some list of objects that you want to avoid:
function isJustObj(obj) {
var notThese = [Function, Array, Date];
if (obj instanceof Object) {
return !notThese.some(function(o) {
return obj instanceof o;
});
}
return false;
}
function Foo(){}
var tests = {'Array: ':[],
'Object: ' : {},
'Foo instance:' : new Foo(),
'Function: ' : function(){},
'Date: ' : new Date(),
'Host obj: ' : document.createElement('div')
};
Object.keys(tests).forEach(function(test) {
console.log(test + isJustObj(tests[test]));
})
Note that this strategy sees if the value is some kind of Object, then tests whether it's an instance of a particular set of constructors. This list of things to exclude can become very large since it's not possible in any reasonable way to rule out host objects which, by their very nature, can be indistinguishable from built-in objects based on some general test (see Is there an environment-agnostic way to detect Javascript Host Objects?).
E.g.
console.log instanceof Function // true
console instanceof Object // true
isPlainObject(console) // false
So you either check if Object.prototype is the immediate [[Prototype]]
or create a long list of constructors to test against. That list will go out of date very quickly given the variety of host environments available and the freedom for implementors to extend it. Also, you need to test every member of the host object set before trying to use it as it may not exist for the particular host on which the code is running.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With