Почему typeof array с объектами возвращает "object", а не "array"?

Возможный дубликат:
JavaScript: Проверить, является ли объект массивом?

Почему массив объектов считается объектом, а не массивом? Например:

$.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
    }
});​

скрипка

Ответ 1

Одно из странных поведений и спецификаций в Javascript - это тип массива Object.

Вы можете проверить, является ли переменная массивом несколькими способами:

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

Но самый надежный способ:

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

Поскольку вы отметили свой вопрос с помощью jQuery, вы можете использовать функцию jQuery isArray:

var isArr = $.isArray(data);

Ответ 2

Цитирование спецификации

15.4 Объекты массива

Объекты массива предоставляют особый подход к определенному классу имен свойств. Имя свойства P (в виде значения String) является индексом массива тогда и только тогда, когда ToString (ToUint32 (P)) равно P и ToUint32 (P) не равно 2 ^ 32-1. Свойство, имя свойства которого является индексом массива, также называется элементом. Каждый объект Array имеет свойство length, значение которого всегда является неотрицательным целым числом меньше 2 ^ 32. Значение свойства length численно больше, чем имя каждого свойства, имя которого является индексом массива; когда свойство объекта Array создается или изменяется, другие свойства корректируются по мере необходимости для поддержания этого инварианта. В частности, всякий раз, когда добавляется свойство, чье имя является индексом массива, свойство length изменяется, если необходимо, на одно больше, чем числовое значение этого индекса массива; и всякий раз, когда свойство length изменяется, каждое свойство, имя которого является индексом массива, значение которого не меньше, чем новая длина, автоматически удаляется. Это ограничение применяется только к собственным свойствам объекта Array и не зависит от свойств индекса длины или массива, которые могут быть унаследованы от его прототипов.

И вот таблица для typeof

enter image description here


Чтобы добавить некоторый фон, в JavaScript есть два типа данных:

  • Примитивные типы данных. Сюда входят null, undefined, string, boolean, number и object.
  • Производные типы данных/Специальные объекты. Сюда входят функции, массивы и регулярные выражения. И да, все они получены из "Объекта" в JavaScript.

Объект в JavaScript похож по структуре на ассоциативный массив/словарь, видимый на большинстве объектно-ориентированных языков - т.е. он имеет набор пар ключ-значение.

Массив можно рассматривать как объект со следующими свойствами/ключами:

  • Длина. Это может быть 0 или выше (неотрицательно).
  • Индексы массива. Под этим я имею в виду "0", "1", "2" и т.д. Все свойства объекта массива.

Надеюсь, что это помогло пролить свет на то, почему typeof Array возвращает объект. Ура!

Ответ 3

Попробуйте этот пример, и вы также поймете, в чем разница между Ассоциативным массивом и объектом в JavaScript.

Ассоциативный массив

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

возвращает true

Имейте в виду, что a.length будет неопределенным, поскольку length рассматривается как ключ, вы должны использовать Object.keys(a).length чтобы получить длину ассоциативного массива.

объект

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

возвращает false

JSON возвращает объект... может возвращать ассоциативный массив... но это не так

Ответ 4

В вашем коде нет простого массива JS. data является родным объектом JS.  Помните о различных значениях разных типов скобок:

var someArray = [];
var someObject = {};