Advertisement
Advertisement


Check if a value is an object in JavaScript


Question

How do you check if a value is an Object in JavaScript?

2017/02/13
1
1448
2/13/2017 10:53:22 AM

Accepted Answer

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".


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.

535
12/26/2019 1:28:29 AM


Let's define "object" in Javascript. According to the MDN docs, every value is either an object or a primitive:

primitive, primitive value

A data that is not an object and does not have any methods. JavaScript has 5 primitive datatypes: string, number, boolean, null, undefined.

What's a primitive?

  • 3
  • 'abc'
  • true
  • null
  • undefined

What's an object (i.e. not a primitive)?

  • Object.prototype
  • everything descended from Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} -- user-defined functions
    • C.prototype -- the prototype property of a user-defined function: this is not Cs prototype
      • new C() -- "new"-ing a user-defined function
    • Math
    • Array.prototype
      • arrays
    • {"a": 1, "b": 2} -- objects created using literal notation
    • new Number(3) -- wrappers around primitives
    • ... many other things ...
  • Object.create(null)
  • everything descended from an Object.create(null)

How to check whether a value is an object

instanceof by itself won't work, because it misses two cases:

// oops:  isObject(Object.prototype) -> false
// oops:  isObject(Object.create(null)) -> false
function isObject(val) {
    return val instanceof Object; 
}

typeof x === 'object' won't work, because of false positives (null) and false negatives (functions):

// oops: isObject(Object) -> false
function isObject(val) {
    return (typeof val === 'object');
}

Object.prototype.toString.call won't work, because of false positives for all of the primitives:

> Object.prototype.toString.call(3)
"[object Number]"

> Object.prototype.toString.call(new Number(3))
"[object Number]"

So I use:

function isObject(val) {
    if (val === null) { return false;}
    return ( (typeof val === 'function') || (typeof val === 'object') );
}

@Daan's answer also seems to work:

function isObject(obj) {
  return obj === Object(obj);
}

because, according to the MDN docs:

The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value. If the value is an object already, it will return the value.


A third way that seems to work (not sure if it's 100%) is to use Object.getPrototypeOf which throws an exception if its argument isn't an object:

// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)

// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})
2020/06/20

underscore.js provides the following method to find out if something is really an object:

_.isObject = function(obj) {
  return obj === Object(obj);
};

UPDATE

Because of a previous bug in V8 and minor micro speed optimization, the method looks as follows since underscore.js 1.7.0 (August 2014):

_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};
2020/01/15

Object.prototype.toString.call(myVar) will return:

  • "[object Object]" if myVar is an object
  • "[object Array]" if myVar is an array
  • etc.

For more information on this and why it is a good alternative to typeof, check out this article.

2013/07/25

For simply checking against Object or Array without additional function call (speed). As also posted here.

isArray()

isArray = function(a) {
    return (!!a) && (a.constructor === Array);
};
console.log(isArray(        )); // false
console.log(isArray(    null)); // false
console.log(isArray(    true)); // false
console.log(isArray(       1)); // false
console.log(isArray(   'str')); // false
console.log(isArray(      {})); // false
console.log(isArray(new Date)); // false
console.log(isArray(      [])); // true

isObject() - Note: use for Object literals only, as it returns false for custom objects, like new Date or new YourCustomObject.

isObject = function(a) {
    return (!!a) && (a.constructor === Object);
};
console.log(isObject(        )); // false
console.log(isObject(    null)); // false
console.log(isObject(    true)); // false
console.log(isObject(       1)); // false
console.log(isObject(   'str')); // false
console.log(isObject(      [])); // false
console.log(isObject(new Date)); // false
console.log(isObject(      {})); // true
2017/05/23

I'm fond of simply:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

If the item is a JS object, and it's not a JS array, and it's not null…if all three prove true, return true. If any of the three conditions fails, the && test will short-circuit and false will be returned. The null test can be omitted if desired (depending on how you use null).

DOCS:

http://devdocs.io/javascript/operators/typeof

http://devdocs.io/javascript/global_objects/object

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null

2015/06/14

Source: https://stackoverflow.com/questions/8511281
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]