views:

165

answers:

3

To check if an element is an array in JavaScript, I have always used Crockford's function (pg 61 of The Good Parts):

var is_array = function (value) {
    return value &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        typeof value.splice === 'function' &&
        !(value.propertyIsEnumerable('length'));
}

But if I'm not mistaken, recently some guy from Google had found a new way on how to test for a JavaScript array, but I just can't remember from where I read it and how the function went.

Can anyone point me to his solution please?


[Update]
The person from Google who apparently discovered this is called Mark Miller.

Now I've also read that from this post that his solution can easily break as well:

// native prototype overloaded, some js libraries extends them
Object.prototype.toString= function(){
  return  '[object Array]';
}

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

var a = {};
alert(isArray(a)); // returns true, expecting false;

So, I ask, is there any way that we can truly check for array validity?

+5  A: 

I believe you are looking for

Object.prototype.toString.call(value) === "[object Array]";

This is the method that jQuery uses to check whether a passed parameter value is a function or array object. There are browser specific instances where using typeof does not yield the correct result

Russ Cam
checked with rhino... works great!
jldupont
FYI the second example is not a valid shorthand. jQuery creates a local `toString` reference that simply points to `Object.prototype.toString`.
Crescent Fresh
Doesn't jQuery define it as a local reference to resolve the call quicker? Since all objects derive from Object, they should all have the toString function
Russ Cam
@Russ: heh, sorry I think we're just saying the same thing. You're right, jQuery simply does `var toString = Object.prototype.toString;`. My point was `Object.prototype.toString !== window.toString`, which invalidates your statement that the second example is equivalent to the first example, that's all :) Cheers.
Crescent Fresh
You could of course, define a toString function on the constructor's prototype and break the shorthand, so duly noted, will remove the shorthand :)
Russ Cam
A: 

Try:

if(value instanceof Array)
{
    alert("Woo");
}
tyranid
The `instanceof` operator fails when comparing arrays across different contexts. See http://blog.brianhartsock.com/2007/03/08/breaking-instanceof-in-javascript/ and http://bytes.com/topic/javascript/answers/91190-myarray-instanceof-array-fails-after-passing-different-page
Andreas Grech
A: 

You could do this:

t = [1,2];
// Now to check if this is an array
if (t.constructor == Array)
{
    alert('t is an array');
}
else
{
    alert('t is NOT an array');
}

Basically, variable.constructor == Array

aip.cd.aish
That fails as well, for the same reasons I told @tyranid. Read the section 'Detecting Object and Array' at this post: http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/
Andreas Grech