tags:

views:

160

answers:

6

What's the 'right' way to tell if an object is an Array?

function isArray(o) { ??? }

A: 

This is what I use:

function is_array(obj) {
  return (obj.constructor.toString().indexOf("Array") != -1)
}
Alex - Aotea Studios
A: 
function typeOf(obj) {
  if ( typeof(obj) == 'object' )
    if (obj.length)
      return 'array';
    else
      return 'object';
    } else
  return typeof(obj);
}
Justin
+6  A: 

The best way:

function isArray(obj) {
  return Object.prototype.toString.call(obj) == '[object Array]';
}

The ECMAScript 5th Edition Specification defines a method for that, and some browsers, like Firefox 3.7alpha, Chrome 5 Beta, and latest WebKit Nightly builds already provide a native implementation, so you might want to implement it if not available:

if (typeof Array.isArray != 'function') {
  Array.isArray = function (obj) {
    return Object.prototype.toString.call(obj) == '[object Array]';
  };
}
CMS
even safer is `return Object.prototype.toString.call(obj) === '[object Array]';` to avoid any possible coersion
Rixius
@Rixius: Well, the `Object.prototype.toString` method is [fully described](http://bclary.com/2004/11/07/#a-15.2.4.2) in the specification, a `String` return value is *guaranteed*, I don't see any benefit of using the strict equals operator, when you know you are comparing two strings values...
CMS
Someone could have bashed the `Object.prototype.toString` always better to be safe than sorry.
Rixius
@Rixius, well, if someone replaced the built-in method, there is not too much to do, imagine: `Object.prototype.toString = function () {return "[object Array]"; };` even with the strict equals `===` operator the function will return `true` always. Crockford says: "always use `===`", I say: learn about type coercion to decide which operator use.
CMS
@CMS that makes sense thanks for the response.
Rixius
@Rixius, you're welcome!
CMS
A: 

You can take take Prototype library definition of method Object.isArray() which test it :

function(object) {
  return object != null && typeof object == "object" &&
   'splice' in object && 'join' in object;
}
Serty Oan
Prototype is not using that method anymore, see [here](http://github.com/sstephenson/prototype/blob/1.6.1/src/lang/object.js#L191) how it's implemented in 1.6.1.
CMS
+1  A: 

You should be able to use the instanceof operator:

var testArray = [];

if (testArray instanceof Array)
    ...
Chad Birch
The only downside of `instanceof` is when you work in a multi-frame DOM environment, an array object form one frame is not instance of the `Array` constructor of other frame. See [this article](http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/) for more details.
CMS