The output of my JSON call can either be an Array or a Hash. How do I distinguish between these two?
7 Answers
Modern browsers support the Array.isArray(obj)
method.
See MDN for documentation and a polyfill.
= original answer from 2008 =
you can use the constuctor property of your output:
if(output.constructor == Array){
}
else if(output.constructor == Object){
}

- 35,827
- 7
- 56
- 53
-
2This has the potential of conflicts between different pages, since they both have different instances of the `Array` and `Object` constructor functions, that won't compare as equal. I'm not quite sure how to produce an example that demonstrates this, but I read it somewhere. – ripper234 May 14 '12 at 11:15
-
1@ripper234 The problem will manifest itself in a multi `window` environment. – alex Nov 11 '12 at 03:55
-
3+1 for metioning Array.isArray. Check this link for borwser support: http://kangax.github.io/compat-table/es5/#Array.isArray – SKuijers Mar 11 '15 at 13:47
-
1Anybody using [underscore.js](http://documentcloud.github.io/underscore/) might find [isArray](http://documentcloud.github.io/underscore/#isArray) and [isObject](http://documentcloud.github.io/underscore/#isObject) useful. – akotian Jul 30 '15 at 16:56
-
1@akotian _.isObject returns true for both array and hash, unfortunately. You'll need additional conditional logic to iron out a solution with underscore. – Con Antonakos Oct 19 '15 at 16:03
-
Pashmam!!! for more information see [this link](https://www.urbandictionary.com/define.php?term=Pashmam) – AmerllicA Aug 21 '18 at 07:39
Is object:
function isObject ( obj ) {
return obj && (typeof obj === "object");
}
Is array:
function isArray ( obj ) {
return isObject(obj) && (obj instanceof Array);
}
Because arrays are objects you'll want to test if a variable is an array first, and then if it is an object:
if (isArray(myObject)) {
// do stuff for arrays
}
else if (isObject(myObject)) {
// do stuff for objects
}

- 37,817
- 5
- 41
- 42
-
1Good answer. You may want to add the every js object can be treated as a hash. – Rontologist Oct 20 '08 at 15:34
-
isObject(new Date())) is true, but a date is not an object/hash in the sense of this question. Of course we just apply it to JSON, but the method name is really confusing then. – schirrmacher Jun 28 '15 at 19:12
-
`isObject` returns true for both objects and arrays so is redundant – hacklikecrack Jul 26 '19 at 11:36
Did you mean "Object" instead of "Hash"?
>>> var a = [];
>>> var o = {};
>>> a instanceof Array
true
>>> o instanceof Array
false

- 61,926
- 17
- 143
- 150
I made a function for determining if it's a dictionary.
exports.is_dictionary = function (obj) {
if(!obj) return false;
if(Array.isArray(obj)) return false;
if(obj.constructor != Object) return false;
return true;
};
// return true
test.equal(nsa_utils.is_dictionary({}), true);
test.equal(nsa_utils.is_dictionary({abc:123, def:456}), true);
// returns false
test.equal(nsa_utils.is_dictionary([]), false);
test.equal(nsa_utils.is_dictionary([123, 456]), false);
test.equal(nsa_utils.is_dictionary(null), false);
test.equal(nsa_utils.is_dictionary(NaN), false);
test.equal(nsa_utils.is_dictionary('hello'), false);
test.equal(nsa_utils.is_dictionary(0), false);
test.equal(nsa_utils.is_dictionary(123), false);

- 50,398
- 25
- 166
- 151
-
Thanks for this. It has worked for the above cases mentioned. I have to yet come across a case where your method fails. – Nav Feb 08 '17 at 08:00
-
1`if(Array.isArray(obj)) return false;` <- Isn't this redundant given that an array will not pass the next check anyway (`if(obj.constructor != Object)`)? – Oct 30 '18 at 07:27
-
`assert.equal(is_dictionary(new (class MyClass {})), true);` fails - the instance of MyClass is definatelly a hash/dictionary. – Angelos Pikoulas Jan 30 '20 at 16:28
-
Improved it a bit: ```const assert = require('assert'); const is_dictionary = function (obj) { if(!obj) return false; if(Array.isArray(obj)) return false; if (({}).toString.apply(obj) !== '[object Object]') return false; return true; }; // returns true along your own with these values new (class MyClass {}) Object.create({}) Object.create(null) // returns false along with yours new String('foo') new Number(123) ()=> {} function() {} new Map ``` – Angelos Pikoulas Jan 30 '20 at 16:35
A more practical and precise term than object or hash or dictionary may be associative array. Object could apply to many undesirables, e.g. typeof null === 'object'
or [1,2,3] instanceof Object
. The following two functions work since ES3 and are mutually exclusive.
function is_array(z) {
return Object(z) instanceof Array;
}
console.assert(true === is_array([]));
console.assert(true === is_array([1,2,3]));
console.assert(true === is_array(new Array));
console.assert(true === is_array(Array(1,2,3)));
console.assert(false === is_array({a:1, b:2}));
console.assert(false === is_array(42));
console.assert(false === is_array("etc"));
console.assert(false === is_array(null));
console.assert(false === is_array(undefined));
console.assert(false === is_array(true));
console.assert(false === is_array(function () {}));
function is_associative_array(z) {
return String(z) === '[object Object]' && ! (Object(z) instanceof String);
}
console.assert(true === is_associative_array({a:1, b:2}));
console.assert(true === is_associative_array(new function Legacy_Class(){}));
console.assert(true === is_associative_array(new class ES2015_Class{}));
console.assert(false === is_associative_array(window));
console.assert(false === is_associative_array(new Date()));
console.assert(false === is_associative_array([]));
console.assert(false === is_associative_array([1,2,3]));
console.assert(false === is_associative_array(Array(1,2,3)));
console.assert(false === is_associative_array(42));
console.assert(false === is_associative_array("etc"));
console.assert(false === is_associative_array(null));
console.assert(false === is_associative_array(undefined));
console.assert(false === is_associative_array(true));
console.assert(false === is_associative_array(function () {}));
Notice how this will treat the instance of a class as an associative array. (But not the instance of a built-in class, such as Date.)
The &&
clause above is a brutish fix for this obscure white-box test:
console.assert(false === is_associative_array("[object Object]"));
Caution: these functions will not be efficient for large or many objects.

- 16,271
- 10
- 88
- 101
Check for "constructor" property on the object. It is Array - it is an array object.
var a = { 'b':{length:0}, 'c':[1,2] } if (a.c.constructor == Array) for (var i = 0; i < a.c.length; i++) alert(a.c[i]); else for (var s in a.b); alert(a.b[s]);

- 31,255
- 9
- 54
- 56
For parsing json could come in handy :)
isArrayHashs = (attr) ->
!!attr && attr.constructor == Array && isHash(attr[0])
isHash = (attr) ->
!!attr && !$.isNumeric(attr) && attr.constructor == Object
attr[0].constructor must be:
- String
- Numeric
- Array
- Object
- Undefined

- 1,015
- 4
- 14
- 21