How do you check if a value is an object in JavaScript?
UPDATE:
This answer is incomplete and gives misleading results. For example, null
is also considered of type object
in JavaScript, not to mention several other edge cases. Follow the recommendation below and move on to other "most upvoted (and correct!) answer":
typeof yourVariable === 'object' && yourVariable !== null
Original answer:
Try using typeof(var)
and/or var instanceof something
.
EDIT: This answer gives an idea of how to examine variable's properties, but it is not a bulletproof recipe (after all there's no recipe at all!) for checking whether it's an object, far from it. Since people tend to look for something to copy from here without doing any research, I'd highly recommend that they turn to the other, most upvoted (and correct!) answer.
Here's an answer with optional chaining, and perhaps the smallest isObj
function for this question.
const isObj = o => o?.constructor === Object;
// True for this
console.log(isObj({})); // object!
// False for these
console.log(isObj(0)); // number
console.log(isObj([])); // array
console.log(isObj('lol')); // string
console.log(isObj(null)); // null
console.log(isObj(undefined)); // undefined
console.log(isObj(() => {})); // function
console.log(isObj(Object)); // class
const isObject = function(obj) {
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
!!obj
is shorthand for checking if obj
is truthy (to filter out null
)
If typeof yourVariable === 'object'
, it's an object or null. If you want to exclude null, just make it typeof yourVariable === 'object' && yourVariable !== null
.
My God, too much confusion in other answers.
Short Answer
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
To test this simply run the following statements in chrome console.
Case 1.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Case 2.
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Case 3.
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
Explanation
Okay.Let's break it down
typeof anyVar == 'object'
is returned true from three candidates - [], {} and null
,
anyVar instanceof Object
narrows down these candidates to two - [], {}
!(anyVar instanceof Array)
narrows to only one - {}
Drum rolls please!
By this you may have already learnt how to check for Array in Javascript.
After reading and trying out a lot of implementations, I've noticed that very few people try to check for values like JSON
, Math
, document
or objects with prototype chains longer than 1 step.
Instead of checking the typeof
of our variable and then hacking away edge-cases, I thought it'd be better if the check is kept as simple as possible to avoid having to refactor when there's new primitives or native objects added that register as typeof
of 'object'.
After all, the typeof
operator will tell you if something is an object to JavaScript, but JavaScript's definition of an object is too broad for most real-world scenarios (e.g. typeof null === 'object'
).
Below is a function that determines whether variable v
is an object by essentially repeating two checks:
v
is '[object Object]'
.v
is replaced with the next prototype in the chain with v = Object.getPrototypeOf(v)
, but also directly evaluated after. When the new value of v
is null
, it means that every prototype including the root prototype (which could very well have been the only prototype inside the chain) have passed the check in the while loop and we can return true. Otherwise, a new iteration starts.function isObj (v) {
while ( Object.prototype.toString.call(v) === '[object Object]')
if ((v = Object.getPrototypeOf(v)) === null)
return true
return false
}
console.log('FALSE:')
console.log('[] -> ', isObj([]))
console.log('null -> ', isObj(null))
console.log('document -> ', isObj(document))
console.log('JSON -> ', isObj(JSON))
console.log('function -> ', isObj(function () {}))
console.log('new Date() -> ', isObj(new Date()))
console.log('RegExp -> ', isObj(/./))
console.log('TRUE:')
console.log('{} -> ', isObj({}))
console.log('new Object() -> ', isObj(new Object()))
console.log('new Object(null) -> ', isObj(new Object(null)))
console.log('new Object({}) -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype -> ', isObj(Object.prototype))
console.log('Object.create(null) -> ', isObj(Object.create(null)))
console.log('Object.create({}) -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance -> ', isObj(Object.create(Object.create({foo: 'bar'}))))