The output of my JSON call can either be an Array or a Hash. How do I distinguish between these two?
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 naturally exclusive.
function is_array(z) {
return Object.prototype.toString.call(z) === '[object 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 Object.prototype.toString.call(z) === '[object Object]';
}
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.)
Thanks to RobG's solution along these lines for an Array.isArray() polyfill. This taps the Object class's native toString() method, which tersely and efficiently reports type.