Why does typeof array with objects return "object" and not "array"?

161,377

Solution 1

One of the weird behaviour and spec in Javascript is the typeof Array is Object.

You can check if the variable is an array in couple of ways:

var isArr = data instanceof Array;
var isArr = Array.isArray(data);

But the most reliable way is:

isArr = Object.prototype.toString.call(data) == '[object Array]';

Since you tagged your question with jQuery, you can use jQuery isArray function:

var isArr = $.isArray(data);

Solution 2

Quoting the spec

15.4 Array Objects

Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32-1. A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 2^32. The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to own properties of an Array object and is unaffected by length or array index properties that may be inherited from its prototypes.

And here's a table for typeof

enter image description here


To add some background, there are two data types in JavaScript:

  1. Primitive Data types - This includes null, undefined, string, boolean, number and object.
  2. Derived data types/Special Objects - These include functions, arrays and regular expressions. And yes, these are all derived from "Object" in JavaScript.

An object in JavaScript is similar in structure to the associative array/dictionary seen in most object oriented languages - i.e., it has a set of key-value pairs.

An array can be considered to be an object with the following properties/keys:

  1. Length - This can be 0 or above (non-negative).
  2. The array indices. By this, I mean "0", "1", "2", etc are all properties of array object.

Hope this helped shed more light on why typeof Array returns an object. Cheers!

Solution 3

Try this example and you will understand also what is the difference between Associative Array and Object in JavaScript.

Associative Array

var a = new Array(1,2,3); 
a['key'] = 'experiment';
Array.isArray(a);

returns true

Keep in mind that a.length will be undefined, because length is treated as a key, you should use Object.keys(a).length to get the length of an Associative Array.

Object

var a = {1:1, 2:2, 3:3,'key':'experiment'}; 
Array.isArray(a)

returns false

JSON returns an Object ... could return an Associative Array ... but it is not like that

Share:
161,377

Related videos on Youtube

Johan
Author by

Johan

Updated on July 08, 2022

Comments

  • Johan
    Johan almost 2 years

    Possible Duplicate:
    JavaScript: Check if object is array?

    Why is an array of objects considered an object, and not an array? For example:

    $.ajax({
        url: 'http://api.twitter.com/1/statuses/user_timeline.json',
        data: { screen_name: 'mick__romney'},
        dataType: 'jsonp',
        success: function(data) {
            console.dir(data); //Array[20]
            alert(typeof data); //Object
        }
    });​
    

    Fiddle

    • pimvdb
      pimvdb over 11 years
      That's how typeof is defined, but you can use Array.isArray.
    • ZAD-Man
      ZAD-Man over 5 years
      It's weird that this is marked as a duplicate of the other question, which looks to be quite different...
    • rosshjb
      rosshjb about 4 years
      This is because the only existing "type"s in ECMAScript are undefined, null, boolean, number, bigint, string, symbol, and object.
  • Johan
    Johan over 11 years
    So in other words, typeof can never return "Array"?
  • pimvdb
    pimvdb over 11 years
    JSON also has the concept of arrays. (And array indices start at 0.)
  • Reflective
    Reflective over 11 years
    The guy defined his data as { ... } - Object ... I'm trying to explain him what's the difference b/w an Associative Array and an Objects. Actually he checks the date returned by the server, so it's not the same ... but may be you are right ... should check it :)
  • Reflective
    Reflective over 11 years
    Can you give an example of Associative Array an JSON? Something like that: jQuery.parseJSON('{"name":"John"}') ... This one is normally accepted as an Object. How do you think JSON represents an associative array?
  • pimvdb
    pimvdb over 11 years
    There is no such thing in JSON what you call an associative array. But I'm not sure what you're trying to say with your answer with respect to the question.
  • Reflective
    Reflective over 11 years
    With all my respect, there is such thing in JavaScript called Associative Array ... check it ... that's what I tried to explain ... and what's the deference when you call isArray. Associative Array is HASH in Perl for example or normaly called Dictionary. JSON have no such kind of representation ..so an Associative array is treated as an Object with properties.
  • pimvdb
    pimvdb over 11 years
    But how does that answer the question? The OP has an array, and typeof gives "object". He's wondering why that happens. In short, the question is: why does typeof [] not give "array"? You didn't really answer that question.
  • Reflective
    Reflective over 11 years
    Answers half the qestions saying that JSON returns an Object, not an Array, and gives some extra info that because of the syntax JSON always parsing Arrays as Objects not as an Associative Array, which could be made because Associative Array exists as a type, but unfortunately JSON is not working like that, and not returnig an Associative Array. Associative Array has some disadvantages and it's good to use Objects. For exampe getting the lenght, which I explained in my answer. So the idea is to understand why they use Objects parsing the JSON string. At least you learned something. Right?
  • pimvdb
    pimvdb over 11 years
    There's nothing wrong with JSON here; data is actually an array. The OP is not using associative arrays at all. The question is why typeof gives "object" when used on an array. But I guess we're speaking on different wavelengths.
  • Reflective
    Reflective over 11 years
    { key: value } defines an Object,not an Array.As you know to define an array you should do ['mick__romney']. The other thing is that the data the guy checks is a result form the AJAX request parser and it have nothing common with the param data: on the AJAX settings. The answer is that JSON translates all Arrais passed by JSON strings to Objects. Can't be deifferent, doesn't matter if they looks like an array. Many ways to manage the problem for ex. try { var a = data.scrren_name; isArray = true; } catch (e) { isArray = false;} ... but it's good to dive a bit deeper into the problem.
  • Reflective
    Reflective over 11 years
    anyway ... it's useless to keep talking about that :) let's tune on the 'newest questions' channel ;)
  • nnnnnn
    nnnnnn over 11 years
    JSON definitely does not "translate all arrays passed by JSON strings to Objects". When parsed, such arrays - using square brackets - become actual JS arrays, not objects. Also, in the first example in your answer a.length will not be undefined, it will be 3.
  • Reflective
    Reflective over 11 years
    About .length - you should first try (as it shown in example above) ... will be doesn't mean it is ... and it is clearly explained why. About Arrays: I was talking about associative arrays, may be it's not clear because I wrote 100s of lines and may I missed that clarification. But please tell me, how an associative array is represented in JSON? Answering youself this questin will finally quit this endless discussion. And when you find that .length is not working for associative array be so brave to tell - "ok, my mistake"
  • nnnnnn
    nnnnnn over 11 years
    JSON representation of an array: "[1,2,3]" - when parsed will create the array [1,2,3] which has a .length of 3 and for which Array.isArray() will return true. I.e., Array.isArray(JSON.parse("[1,2,3]")) is true (try it). What you call an "associative array" in your answer is a standard JS array with additional non-numeric properties added, and that can not be represented in JSON (other than as a non-array object that you'd have to convert to an array).
  • nnnnnn
    nnnnnn over 11 years
    P.S. In your example a.length will be 3 - you try it, you are the one who is mistaken here. The length property will be one higher than the highest numerically indexed property in the array, i.e., it ignores any additional non-numeric properties that you add such as your a['key'] example - but length will not be undefined - perhaps that is what you were trying to say. An "associative array" exists in other languages, but in JavaScript the closest thing is a plain object.
  • Reflective
    Reflective over 11 years
    Probably it depends on the browser my master but anyway it is not the correct length ... If you have just keys it will be 0, but I'm glad that you finally understood what I'm talking about. I'm not talking about array "[1,2,3]" which is absolutelly regular array. Read carefully. Adding a key 'key' makes it Associative one (HASH, Dictionary). Its not me who gives the names,that's how it's called. For the last time: there's a differens b/w an assoc. array and Object - isArray will return true for an assoc. array and false for an Object. Google: associative array javascript
  • Reflective
    Reflective over 11 years
    Reading your answers I think you never heard about Associative Arrays and don't believe in their existance :) Anyway, this kind of discussin is useless. Won't spend my time in contaversy for the things that could be easily checked.
  • Alex
    Alex about 10 years
    "But the most reliable way is: ... " So the other ways you suggested are unreliable?
  • gdoron is supporting Monica
    gdoron is supporting Monica about 10 years
    @Alex, yes, the other can give you false if you're checking an array you got from an <iframe>.
  • Mark Fox
    Mark Fox almost 9 years
    @gdoron MDN seems to indicate that Array.isArray(…) should be reliable developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…?
  • gdoron is supporting Monica
    gdoron is supporting Monica almost 9 years
    @m, You're right, but not supported on older browsers. see here
  • Jan Chalupa
    Jan Chalupa over 8 years
    You can determine if you have array or object using this way: if(typeof myArrayOfObject[0] == "object"). If true then you have object, if false then you have array.
  • Potatoes
    Potatoes almost 7 years
    object is not primitive according to : developer.mozilla.org/en-US/docs/Glossary/Primitive
  • Romesh
    Romesh over 3 years
    I got ["1"] instanceof Object as true. Is checking with data instanceof Array reliable?