[javascript] How to check if an object is an array?

I'm trying to write a function that either accepts a list of strings, or a single string. If it's a string, then I want to convert it to an array with just the one item so I can loop over it without fear of an error.

So how do I check if the variable is an array?


I've rounded up the various solutions below and created a jsperf test. They're all fast, so just use Array.isArray -- it's well-supported now and works across frames.

This question is related to javascript arrays javascript-objects

The answer is


You can also check with array's length property. When you will try to access length property of an array, it will return a number(0 for empty array) while if you try to access the length property of object it will return undefined.

if(Object.prototype.toString.call(arrayList) === '[object Array]') {
  console.log('Array!');
}

Here's my lazy approach:

if (Array.prototype.array_ === undefined) {
  Array.prototype.array_ = true;
}

// ...

var test = [],
    wat = {};

console.log(test.array_ === true); // true
console.log(wat.array_ === true);  // false

I know it's sacrilege to "mess with" the prototype, but it appears to perform significantly better than the recommended toString method.

Note: A pitfall of this approach is that it wont work across iframe boundaries, but for my use case this is not an issue.


I do this in a very simple way. Works for me. Any drawbacks?

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)

easiest and fastest way to check if an Object is an Array or not.

 var arr = [];
  arr.constructor.name ==='Array'  //return true;

or

arr.constructor ===Array //return true;

or you can make a utility function:

const isArray = (obj)=> !!obj && obj.constructor ===Array;

usage:

isArray(arr); //return true

function isArray(value) {
    if (value) {
        if (typeof value === 'object') {
            return (Object.prototype.toString.call(value) == '[object Array]')
        }
    }
    return false;
}

var ar = ["ff","tt"]
alert(isArray(ar))

You could is isArray method but I would prefer to check with

Object.getPrototypeOf(yourvariable) === Array.prototype


The best solution I've seen is a cross-browser replacement for typeof. Check Angus Croll's solution here.

The TL;DR version is below, but the article is a great discussion of the issue so you should read it if you have time.

Object.toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
// ... and usage:
Object.toType([1,2,3]); //"array" (all browsers)

// or to test...
var shouldBeAnArray = [1,2,3];
if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */};

I have updated the jsperf fiddle with two alternative methods as well as error checking.

It turns out that the method defining a constant value in the 'Object' and 'Array' prototypes is faster than any of the other methods. It is a somewhat surprising result.

_x000D_
_x000D_
/* Initialisation */_x000D_
Object.prototype.isArray = function() {_x000D_
  return false;_x000D_
};_x000D_
Array.prototype.isArray = function() {_x000D_
  return true;_x000D_
};_x000D_
Object.prototype._isArray = false;_x000D_
Array.prototype._isArray = true;_x000D_
_x000D_
var arr = ["1", "2"];_x000D_
var noarr = "1";_x000D_
_x000D_
/* Method 1 (function) */_x000D_
if (arr.isArray()) document.write("arr is an array according to function<br/>");_x000D_
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");_x000D_
/* Method 2 (value) - **** FASTEST ***** */_x000D_
if (arr._isArray) document.write("arr is an array according to member value<br/>");_x000D_
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");
_x000D_
_x000D_
_x000D_

These two methods do not work if the variable takes the undefined value, but they do work if you are certain that they have a value. With regards to checking with performance in mind if a value is an array or a single value, the second method looks like a valid fast method. It is slightly faster than 'instanceof' on Chrome, twice as fast as the second best method in Internet Explorer, Opera and Safari (on my machine).


I would make a function to test the type of object you are dealing with...

_x000D_
_x000D_
function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }_x000D_
_x000D_
// tests_x000D_
console.log(_x000D_
  whatAmI(["aiming","@"]),_x000D_
  whatAmI({living:4,breathing:4}),_x000D_
  whatAmI(function(ing){ return ing+" to the global window" }),_x000D_
  whatAmI("going to do with you?")_x000D_
);_x000D_
_x000D_
// output: Array Object Function String
_x000D_
_x000D_
_x000D_

then you can write a simple if statement...

if(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}

Array.isArray is the way to go about this. For example:

var arr = ['tuna', 'chicken', 'pb&j'];
var obj = {sandwich: 'tuna', chips: 'cape cod'};

// Returns true
Array.isArray(arr);

// Return false
Array.isArray(obj);


The best practice is to compare it using constructor, something like this

if(some_variable.constructor === Array){
  // do something
}

You can use other methods too like typeOf, converting it to a string and then comparing but comparing it with dataType is always a better approach.


There is a nice example in Stoyan Stefanov's book JavaScript Patterns which suppose to handle all possible problems as well as utilize ECMAScript 5 method Array.isArray().

So here it is:

if (typeof Array.isArray === "undefined") {
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
}

By the way, if you are using jQuery, you can use it's method $.isArray()


I would first check if your implementation supports isArray:

if (Array.isArray)
    return Array.isArray(v);

You could also try using the instanceof operator

v instanceof Array

there is a difference between checkout it's prototype and Array.isArray:

function isArray(obj){
    return Object.getPrototypeOf(obj) === Array.prototype
}

this function will directly check if an obj is an array

but for this Proxy object:

var arr = [1,2,3]

var proxy = new Proxy(arr,{})

console.log(Array.isArray(proxy)) // true

Array.isArray will take it as Array.


This is the fastest among all methods (all browsers supported):

function isArray(obj){
    return !!obj && obj.constructor === Array;
}

Array.isArray works fast, but it isn't supported by all versions of browsers. So you could make an exception for others and use universal method:

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }

Exotic one

You want to check if the parameter is string or not - so try

x===x+''

_x000D_
_x000D_
let isStr = x=> x===x+'';_x000D_
_x000D_
console.log( isStr([]) );_x000D_
console.log( isStr(["aa","bb"]) );_x000D_
console.log( isStr("") );_x000D_
console.log( isStr("abc") );
_x000D_
_x000D_
_x000D_


As MDN says in here:

use Array.isArray or Object.prototype.toString.call to differentiate regular objects from arrays

Like this:

  • Object.prototype.toString.call(arr) === '[object Array]', or

  • Array.isArray(arr)


The method given in the ECMAScript standard to find the class of Object is to use the toString method from Object.prototype.

if( Object.prototype.toString.call( someVar ) === '[object Array]' ) {
    alert( 'Array!' );
}

Or you could use typeof to test if it is a String:

if( typeof someVar === 'string' ) {
    someVar = [ someVar ];
}

Or if you're not concerned about performance, you could just do a concat to a new empty Array.

someVar = [].concat( someVar );

There's also the constructor which you can query directly:

if (somevar.constructor.name == "Array") {
    // do something
}

Check out a thorough treatment from @T.J. Crowder's blog, as posted in his comment below.

Check out this benchmark to get an idea which method performs better: http://jsben.ch/#/QgYAV

From @Bharath convert string to array using Es6 for the question asked:

const convertStringToArray = (object) => {
   return (typeof object === 'string') ? Array(object) : object 
}

suppose:

let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']

You can use this function to get data type.

var myAr  = [1,2];

checkType(myAr);

function checkType(data){
  if(typeof data ==='object'){
    if(Object.prototype.toString.call(data).indexOf('Array')!==(-1)){
      return 'array';
    } else{
      return 'object';
    }
  } else {
    return typeof data;
  }
}

if(checkType(myAr) === 'array'){console.log('yes, It is an array')};

There's just one line solution for this question

x instanceof Array

where x is the variable it will return true if x is an array and false if it is not.


A = [1,2,3]
console.log(A.map==[].map)

In search for shortest version here is what I got so far.

Note, there is no perfect function that will always detect all possible combinations. It is better to know all abilities and limitations of your tools than expect a magic tool.


Imagine you have this array below:

var arr = [1,2,3,4,5];

Javascript (new and older browsers):

function isArray(arr) {
  return arr.constructor.toString().indexOf("Array") > -1;
}

or

function isArray(arr) {
  return arr instanceof Array;
}

or

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

then call it like this:

isArray(arr);

Javascript (IE9+, Ch5+, FF4+, Saf5+, Opera10.5+)

Array.isArray(arr);

jQuery:

$.isArray(arr);

Angular:

angular.isArray(arr);

Underscore and Lodash:

_.isArray(arr);

A simple function for testing if an input value is an array is the following:

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

This works cross browser, and with older browsers. This is pulled from T.J. Crowders' blog post


Array.isArray(obj), does not give very helpful results. I've created a prototype method of Object, that seems to correctly determine whether and object is an array or not.

The only edge case that I know of where it fails is when item in the array is set to undefined.

Object.prototype.isArrayLike = function()
{
    var length = this.length || Object.keys(this).length;
    if (length === 0 || this.constructor.name === "String")
        return false;
    for (i = 0; i < length; i++)
    {
        if (typeof this[i] === "undefined")
            return false;
    }
    return true;
};

var arr = ['aaa', 'bbb', 'ccc', 'ddd'];
var arr1 = {"0":'aaa', "1":'bbb', 2:'ccc', 3:'ddd'};
var arr2 = {"0":'aaa', "a":'bbb', 2:'ccc', 3:'ddd'};
var arr3 = "qwerty";
var arr4 = [];
var arr5 = {0:'aaa', 1:'bbb', 2:'ccc', 3:'ddd'};

console.log("arrayLike:" + arr.isArrayLike());
console.log("Array.isArray(arr):" + Array.isArray(arr));
// arrayLike: true
// Array.isArray(arr): true
console.log("arrayLike1:" + arr1.isArrayLike());
console.log("Array.isArray(arr1):" + Array.isArray(arr1));
// arrayLike1: true
// Array.isArray(arr1): false
console.log("arrayLike2:" + arr2.isArrayLike());
console.log("Array.isArray(arr2):" + Array.isArray(arr2));
// arrayLike2: false
// Array.isArray(arr2): false
console.log("arrayLike3:" + arr3.isArrayLike());
console.log("Array.isArray(arr3):" + Array.isArray(arr3));
// arrayLike3: false
// Array.isArray(arr3): false
console.log("arrayLike4:" + arr4.isArrayLike());
console.log("Array.isArray(arr4):" + Array.isArray(arr4));
// arrayLike4: false
// Array.isArray(arr4): true
console.log("arrayLike5:" + arr5.isArrayLike());
console.log("Array.isArray(arr5):" + Array.isArray(arr5));
// arrayLike5: false
// Array.isArray(arr5): true

Since I don't like any Object.prototype-calls, I searched for another solution. Especially because the solutions of ChaosPandion won't always work, and the solution of MidnightTortoise with isArray() doesn't work with arrays coming from the DOM (like getElementsByTagName). And finally I found an easy and cross-browser solution, which probably also would have worked with Netscape 4. ;)

It's just these 4 lines (checking any object h):

function isArray(h){
    if((h.length!=undefined&&h[0]!=undefined)||(h.length===0&&h[0]===undefined)){
        return true;
    }
    else{ return false; }
}

I already tested these arrays (all return true):

1) array=d.getElementsByName('some_element'); //'some_element' can be a real or unreal element
2) array=[];
3) array=[10];
4) array=new Array();
5) array=new Array();
   array.push("whatever");

Can anybody confirm that this works for all cases? Or does anybody find a case where my solution don't work?


You can find with push like below:

_x000D_
_x000D_
function isArray(obj){_x000D_
   return (typeof obj.push=== 'function')?true:false;_x000D_
}_x000D_
_x000D_
var array=new Array();_x000D_
or_x000D_
var array=['a','b','c'];_x000D_
console.log(isArray(array));
_x000D_
_x000D_
_x000D_


I know, that people are looking for some kind of raw javascript approach. But if you want think less about, take a look here: http://underscorejs.org/#isArray

_.isArray(object) 

Returns true if object is an Array.

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

first you can check console.log(typeof Object)

if the output is object then var {data}=object ie just destructure the object according to the object keys. and the function can be like this.

const abc=(str1,str2=null)=>{


     var result=[];
      result.push(str1);result.push(str2);
      return result.join("");

}

I know this is an old question, but i found the shortest answer now:

_x000D_
_x000D_
var x = [1,2,3]_x000D_
console.log(x.map?1:0)
_x000D_
_x000D_
_x000D_


Here's what I use:

function isArray(input) {
  if (input instanceof Array || Object.prototype.toString.call(input) === '[object Array]') {
        return true;
  } else return false;
}

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

This function has been taken from "JS the good parts" book, works perfect for me.


You can check the type of your variable whether it is an array with;

var myArray=[];

if(myArray instanceof Array)
{
....
}

You can try this:

var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();

arr.constructor.prototype.hasOwnProperty('push') //true

obj.constructor.prototype.hasOwnProperty('push') // false

Here's a code snippet that'll explain an important fact of arrays that should be known early on while learning JS (unlike me).

_x000D_
_x000D_
// this functions puts a string inside an array_x000D_
var stringInsideArray = function(input) {_x000D_
  if (typeof input === 'string') {_x000D_
    return [input];_x000D_
  }_x000D_
  else if (Array.isArray(input)) {_x000D_
    return input;_x000D_
  } _x000D_
  else {_x000D_
    throw new Error("Input is not a string!");_x000D_
  }_x000D_
}_x000D_
_x000D_
var output = stringInsideArray('hello');_x000D_
console.log('step one output: ', output); // ["hello"]_x000D_
_x000D_
// use typeof method to verify output is an object_x000D_
console.log('step two output: ', typeof output); // object_x000D_
_x000D_
// use Array.isArray() method to verify output is an array_x000D_
console.log('step three output: ', Array.isArray(output)); // true
_x000D_
_x000D_
_x000D_

Arrays, are in fact, objects.

Using the typeof operator, the output of stringInsideArray('hello') proves that ["hello"] is really an object. This baffled me for the longest time because I assumed that arrays would be a JavaScript data type...

There are only 7 JS data types and arrays are NOT one of them.

To answer your question, using the Array.isArray() method determines that the output is an array.


I know this is an old question but here is a solution that I came up with and have been using for my projects...

function isArray (o) {
    return typeof o === "object" && o.length !== undefined;
}

isArray({}); // false
isArray(1); // false
isArray("str"); // false
isArray(function(){}); // false

isArray([]); // true

The only pitfall is that it will give a false positive if your object happens to have a length property:

isArray({length:0}); // true

If you are okay with that drawback and know your pure objects won't have that property, it's a clean solution and should be faster than the Object.prototype.toString.call method.


var a = [], b = {};

console.log(a.constructor.name == "Array");
console.log(b.constructor.name == "Object");

If the only two kinds of values that could be passed to this function are a string or an array of strings, keep it simple and use a typeof check for the string possibility:

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}

In your case you may use concat method of Array which can accept single objects as well as array (and even combined):

function myFunc(stringOrArray)
{
  var arr = [].concat(stringOrArray);

  console.log(arr);

  arr.forEach(function(item, i)
  {
    console.log(i, "=", item);
  })
}

myFunc("one string");

myFunc(["one string", "second", "third"]);

concat seems to be one of the oldest methods of Array (even IE 5.5 knows it well).


Simple function to check this:

function isArray(object)
{
    return object.constructor === Array;
}

This function will turn almost anything into an array:

function arr(x) {
    if(x === null || x === undefined) {
        return [];
    }
    if(Array.isArray(x)) {
        return x;
    }
    if(isString(x) || isNumber(x)) {
        return [x];
    }
    if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
        return Array.from(x);
    }
    return [x];
}

function isString(x) {
    return Object.prototype.toString.call(x) === "[object String]"
}

function isNumber(x) {
    return Object.prototype.toString.call(x) === "[object Number]"
}

It uses some newer browser features so you may want to polyfill this for maximum support.

Examples:

> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]

N.B. strings will be converted into an array with a single element instead of an array of chars. Delete the isString check if you would prefer it the other way around.

I've used Array.isArray here because it's the most robust and also simplest.


Other methods also exist to check but I prefer the following method as my best to check (as you can easily check types of other objects).

> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'

Explanation (with simple examples on Node REPL)»

> o = {'ok': 1}
{ ok: 1 }
> a = [1, 2]
[ 1, 2 ]
> typeof o
'object'
> typeof a
'object'
>
> Object.prototype.toString.call(o)
'[object Object]'
> Object.prototype.toString.call(a)
'[object Array]'
>

Object or Array »

> Object.prototype.toString.call(o).slice(8,).replace(/\]$/, '')
'Object'
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>

Null or Undefined »

> Object.prototype.toString.call(undefined).slice(8,).replace(/\]$/, '')
'Undefined'
> Object.prototype.toString.call(null).slice(8,).replace(/\]$/, '')
'Null'
>

String »

> Object.prototype.toString.call('ok').slice(8,).replace(/\]$/, '')
'String'

Number »

> Object.prototype.toString.call(19).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.0).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.7).slice(8,).replace(/\]$/, '')
'Number'
>

I appreciate @mpen's suggestion to use -1 in place of regular expression as follows.

> Object.prototype.toString.call(12).slice(8,-1)
'Number'
>
> Object.prototype.toString.call(12.0).slice(8,-1)
'Number'
>
> Object.prototype.toString.call([]).slice(8,-1)
'Array'
> Object.prototype.toString.call({}).slice(8,-1)
'Object'
>
> Object.prototype.toString.call('').slice(8,-1)
'String'
>

This is my attempt to improve on this answer taking into account the comments:

var isArray = myArray && myArray.constructor === Array;

It gets rid of the if/else, and accounts for the possibility of the array being null or undefined


 var length = 16;                               // Number
 var lastName = "Johnson";                      // String
 var cars = ["Saab", "Volvo", "BMW"];           // Array
 var x = {firstName:"John", lastName:"Doe"};

 Object.prototype.myCheck= function(){
 if (this.constructor === Array){
          alert('array');
        }else if (this.constructor === Object)
       {
         alert('object');
        }else if (this.constructor === Number)
        {
          alert('number');
        }else if (this.constructor === String)
        {
          alert('string');
        }

 }
 cars.myCheck();
 lastName.myCheck();
 length.myCheck();

The following could be used if you know that your object doesn't have a concat method.

_x000D_
_x000D_
var arr = [];_x000D_
if (typeof arr.concat === 'function') {_x000D_
    console.log("It's an array");_x000D_
}
_x000D_
_x000D_
_x000D_


jQuery also offers an $.isArray() method:

_x000D_
_x000D_
var a = ["A", "AA", "AAA"];_x000D_
_x000D_
if($.isArray(a)) {_x000D_
  alert("a is an array!");_x000D_
} else {_x000D_
  alert("a is not an array!");_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_


https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray

Array.isArray = Array.isArray || function (vArg) {
    return Object.prototype.toString.call(vArg) === "[object Array]";
};

Although there's some solid answers I would prefer a functional approach using a Functor. A Functor is just a fancy way to say that we will be passing a function to a value. (The suggestions that I've seen are passing values to a function)

Create a TypeOf helper

const TypeOf = obj => Object.prototype.toString.call(obj).slice(8,-1);

This is similar to typeof but now returns Array for [] and Object for {}. I like to think of it as a strict typeof. If you're working on the gmail application and performance is a concern then you can do something like this.

const TypeOf = obj => (
  Array.isArray(obj)
   ? "array"
    : obj === null // catch null edge case.  typeof null is an object :)
   ? null
    : typeof obj
)

You could stop here and call it a day, however you could make it a bit more powerful using composition. You get a lot of benefits if you created a TypeBox Functor, again fancy word for passing a function to a value instead of passing a value to a function.

Create TypeBox

const TypeBox = (predicate, defaultValue) => {
  const TypePredicate = value => ({
     value,
     map: cb => predicate(value)
                ? TypePredicate(cb(value))
                : TypePredicate(defaultValue)
  });
  return TypePredicate;
}

There's a lot going on here, but it's very powerful. The TypeBox function uses a closure and returns our Functor. Closures give you access to Lexical_Scope, think of it as a backpack that holds the things you want access to later.

Create ArrayBox

const ArrayBox = TypeOf(obj => TypeOf(obj) === 'Array' ? obj : [obj]);

ArrayBox is passing our predicate and defaultValue to TypeOf and will be available when we invoke/execute ArrayBox(name it whatever makes sense for your use case).

Now the fun part

If the input is an Array, return it.

ArrayBox(["foo", "bar"]).value; // ['foo', 'bar']

If the input is not an array, return it in one

ArrayBox("foo").value // ["foo"]

What's great about this approach is that it scales, is easy to test, and it uses composition. You can compose the functions in any manner to get the desired result.

There's many other ways we could approach this using Either or Monads.


Thankfully, ECMA 5 introduced Array.isArray() back in December 2009. If for some reason, you are using a version of JavaScript older than ECMA 5, please upgrade.

If you insist on it, though, then arrays do have certain properties that differentiate them from any other type. Properties that I haven't seen mentioned in any of the other answers. Let's get into some JavaScript politics.

An array is an object (typeof [] === "object"), but unlike traditional objects, they have a length property (typeof ( {} ).length === "undefined"). null is also an object (typeof null === "object"), but you can't access a property of null because null is not an object. This is a bug in the spec that goes all the way back to the very beginning of JavaScript, when objects had the type tag 0 and null was represented as a literal null pointer 0x00, which caused the interpreter to confuse it with objects.

Unfortunately, this doesn't account for [] vs {length:0}. So we must now turn to the prototype chain.

( [] ).__proto__ === Array.prototype && ( [] ).__proto__ !== Object.prototype.

Thus, without Array.isArray(), this is just about the closest we can get:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && array.__proto__ === Array.prototype;
}

[ [], [1,2,3], {length: 0}, {},
  1, 0, Infinity, NaN, "1", "[1,2,3]",
  null, undefined, [null], [undefined], {a:[]},
  [{}], [{length: 0}], [Infinity], [NaN],
  {__proto__: Array.prototype}
].filter(is_array)
// Expected: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN] ]
// Actual:   [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN], {__proto__: Array.prototype} ]

The object maliciously designed to look just like an array actually passes the turing test. However, replacing the prototype chain with the Array prototype chain is enough to make it act just like an array, effectively making it an array. The only thing in the world that can tell such an object is actually not an array, is Array.isArray(). But for the purposes you would usually be checking if an object is an array, said object should play nice with your code. Even the behavior when you change the length of the array artificially is the same: if the length is longer than the number of elements in the array, you WILL have "empty slots" of that special "implicit undefined" type that is somehow distinct from undefined while also being === undefined; the very same type that is the reason we use typeof obj !== "undefined" to avoid throwing a ReferenceError because obj === undefined only doesn't throw an error if obj was explicitly defined as undefined.

a = {__proto__: Array.prototype}; // Array {}
a.push(5)
a // [5]
a.length = 5
a // [5, empty x 4]
b = a.map(n => n*n) // [25, empty x 4]
b.push(undefined)
b.push(undefined)
b // [25, empty x 4, undefined, undefined]
b[1] // undefined
b[1] === b[5] // true
Array.isArray(a) // false
Array.isArray(b) // true

Don't use is_array(), though. It's one thing to reinvent the wheel for learning purposes. It's another thing to do it in production code. Don't even use it as a polyfill. Supporting old JS versions means supporting old browsers means encouraging the use of insecure software means putting the user at risk for malware.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to javascript-objects

Cannot read property 'style' of undefined -- Uncaught Type Error Is this a good way to clone an object in ES6? What’s the difference between “{}” and “[]” while declaring a JavaScript array? Comparing two arrays of objects, and exclude the elements who match values into new array in JS Converting JavaScript object with numeric keys into array From an array of objects, extract value of a property as array How to copy JavaScript object to new variable NOT by reference? Remove property for all objects in array Using curl POST with variables defined in bash script functions How to sum the values of a JavaScript object?