Как проверить, является ли переменная массивом в JavaScript?

Я хотел бы проверить, является ли переменная массивом или отдельным значением в JavaScript.

Я нашел возможное решение ...

if (variable.constructor == Array)...

Это лучший способ сделать это?


person Andy McCluggage    schedule 20.04.2009    source источник
comment
Проверка того, является ли объект массивом, имеет некоторые особые предостережения ... Ответ Питера - единственный, который вам следует использовать.   -  person aleemb    schedule 20.04.2009
comment
@Andy Похоже, мой ответ не самый лучший. Может, стоит выбрать другой ответ как принятый?   -  person Peter Smit    schedule 07.08.2011
comment
Хорошее замечание, Питер. Я не понимал, что ваш ответ получал подобные комментарии. Я думаю, что уже давно начал использовать функцию JQuery.isArray при проверке массивов, и что интересно, это реализовано иначе, чем любой другой ответ, приведенный здесь. Я отметил популярный ответ как правильный.   -  person Andy McCluggage    schedule 08.08.2011
comment
Извините, что это неправильно. Я посмотрел немного глубже и (начиная с версии 1.6.2) JQuery по-прежнему проверяет типы, используя сравнения в форме .... toString.call (obj) === [массив объектов]   -  person Andy McCluggage    schedule 08.08.2011
comment
Для поддержки IE8 я бы сделал это if ('push' in variable.__proto__), самый быстрый и, возможно, лучший способ проверить, является ли некоторый var массивом.   -  person thednp    schedule 06.07.2015
comment
jsben.ch/#/QgYAV - эталон наиболее распространенных способов   -  person EscapeNetscape    schedule 24.10.2016
comment
comment
Этот вопрос задавали раньше ... НЕТ, этот вопрос был задан ПОСЛЕ этого   -  person Dexygen    schedule 12.11.2017
comment
Опять же, это StackOverflow   -  person Peppa    schedule 27.07.2020


Ответы (23)


Есть несколько способов проверить, является ли переменная массивом или нет. Лучшее решение - это то, что вы выбрали.

variable.constructor === Array

Это самый быстрый способ в Chrome и, скорее всего, во всех других браузерах. Все массивы являются объектами, поэтому проверка свойства конструктора - быстрый процесс для движков JavaScript.

Если у вас возникают проблемы с выяснением того, является ли свойство объектов массивом, вы должны сначала проверить, существует ли это свойство.

variable.prop && variable.prop.constructor === Array

Некоторые другие способы:

Array.isArray(variable)

Обновление от 23 мая 2019 г. с использованием Chrome 75, спасибо @AnduAndrici за то, что он попросил меня вернуться к этому вопросу с его вопросом. Последний, на мой взгляд, самый уродливый и один из самых медленных самый быстрый. Он работает примерно на 1/5 скорости, как в первом примере. Этот парень примерно на 2-5% медленнее, но это довольно сложно сказать. Надежный в использовании! Вполне впечатлен результатом. Array.prototype, на самом деле является массивом. вы можете прочитать об этом здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

variable instanceof Array

В первом примере этот метод работает примерно на 1/3 скорости. По-прежнему довольно солидный, выглядит чище, если вам нужен красивый код, а не производительность. Обратите внимание, что проверка чисел не работает, поскольку variable instanceof Number всегда возвращает false. Обновление: instanceof теперь работает на 2/3 скорости!

Итак, еще одно обновление

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

Этот парень медленнее всех пытается проверить массив. Однако это универсальный магазин для любого типа, который вы ищете. Однако, поскольку вы ищете массив, просто используйте самый быстрый метод, описанный выше.

Кроме того, я провел несколько тестов: http://jsperf.com/instanceof-array-vs-array-isarray/35 Так что повеселитесь и проверьте это.

Примечание. @EscapeNetscape создал еще один тест, поскольку jsperf.com не работает. http://jsben.ch/#/QgYAV Я хотел убедиться, что исходная ссылка остается всегда, когда jsperf возвращается в онлайн.

person jemiloii    schedule 29.10.2014
comment
Чтобы расширить данный ответ, еще один тест jsperf здесь с использованием тестирования функций (. push && .pop), который является самым быстрым и поддерживается всеми браузерами (даже старыми). Загвоздка в том, что, возможно, объект имеет свойства push и pop, но не является массивом. Также обратите внимание, что при тестировании массива с объектом, созданным (или переданным) из другого кадра, большинство тестов завершатся ошибкой (поскольку Массив в данном окне отличается от Массив в окне фрейма). Также есть загвоздка, если массив создается с помощью new Array или буквально как [..] - person Nikos M.; 15.12.2014
comment
Интересно, мне нужно будет сделать еще несколько тестов браузера. Chrome 38 на centos 7 имеет push && pop на 10% быстрее, чем конструктор, однако chrome 39 на windows 8 имеет конструктор как самый быстрый без тщательного сравнения, поскольку конструктор работает на 70% быстрее, чем push && pop. Я просто подожду еще одного теста, спасибо! - person jemiloii; 17.12.2014
comment
Обратите внимание: если вы не уверены, определена ли переменная или она может иметь значение NULL, обязательно сначала выполните эти проверки, поскольку это общие значения / объекты, у которых нет конструктора. - person Michael Scott Cuthbert; 12.01.2015
comment
Я просто сосредоточился на части массива. Вы можете легко использовать variable && variable.constructor === Array, чтобы убедиться, что переменная не пуста или не определена. - person jemiloii; 12.01.2015
comment
Дополнительные методы: !!~variable.constructor.toString().indexOf('Array()'), variable.constructor.toString() == Array().constructor.toString() (вероятно, будут немного медленными) и Object.prototype.toString.call(variable) == '[object Array]' - person Ismael Miguel; 26.03.2015
comment
variable.constructor быстрее только для проверки реальных массивов. При проверке случайных объектов (а в реальном мире так и будет, потому что вы используете эту функцию) быстрее использовать instanceof. jsperf.com/check-if-variable-is-array - person Dinu Sorin; 16.03.2016
comment
Используя Chrome 50.0.2657.0 на Centos 7, конструктор по-прежнему работает быстрее. Кроме того, конструктор можно использовать для всего, кроме undefined и null. Вы можете просто сделать variable && variable.constructor. Также следует отметить, что 5 instanceof Number не работает должным образом. Экземпляр ищет прототип, числа не имеют прототипа, если вы его не указали. У чисел есть конструкторы. - person jemiloii; 16.03.2016
comment
Еще одно странное замечание: `Object.prototype.toString.call (1) === '[object Number]';` - это вещь. Javascript необычный, поэтому у Numbers есть прототипы. Просто instanceof ими не пользуется. Что странно, потому что это единственная цель, согласно MDN ... - person jemiloii; 16.03.2016
comment
ПРИМЕЧАНИЕ: 'variable.constructor === Array' выдаст ИСКЛЮЧЕНИЕ, если переменная имеет значение NULL, а 'variable instanceof Array' - нет! - person GorvGoyl; 05.10.2016
comment
если вы посмотрите, я привел пример variable && variable.constructor === Array - person jemiloii; 05.10.2016
comment
Array.isArray(variable) у меня даже не работал. Первый отлично справился! - person awe; 20.09.2017
comment
@awe в каком браузере вы это используете? - person jemiloii; 20.09.2017
comment
Согласно опубликованному вами JSPerf, Array.isArray - самый быстрый, а не самый медленный - person Ferrybig; 25.09.2017
comment
какой у вас браузер и версия? Для меня chrome / firefox, который я быстро протестировал, конструктор по-прежнему остается самым быстрым, однако было заметное улучшение для массивов, состоящих только из строк. Массивы, состоящие только из строк, работают очень быстро. Я проведу еще тесты. - person jemiloii; 25.09.2017
comment
В Chrome 59 isArray () кажется значительно быстрее, поэтому я не вижу причин не использовать isArray () во всех ситуациях. - person Hedley Smith; 10.10.2017
comment
В исходном вопросе производительность не упоминалась. Эти микрооптимизации будут несущественными почти для всех случаев использования. - person Drenai; 15.02.2018
comment
Некоторым людям нравится предоставлять дополнительную информацию вместо минимума :) - person jemiloii; 18.02.2018
comment
Все ваши тесты ошибочны - как потому, что V8 (Chrome) изменил JIT-компиляторы, так и потому, что ваши тесты не актуальны. Я рекомендую вам заглянуть в блог mraleph о производительности и, в частности, о jsperf. JSPerf похож на то, как микросхемы не существуют, а морфизм функции не имеет отношения к компилятору, тогда как на практике характеристики производительности сильно различаются в зависимости от того, что может доказать движок. - person Benjamin Gruenbaum; 06.07.2018
comment
А именно, V8 может - person Benjamin Gruenbaum; 06.07.2018
comment
variable.constructor === Array по-прежнему является принятым ответом как самый быстрый / самый эффективный? или variable instanceof Array или Array.isArray(variable) стали более жизнеспособными? - спрашивать, поскольку ответы / комментарии в некоторых местах довольно старые. Очень признателен :) - person Andu Andrici; 21.05.2019
comment
Просто запустите тесты, чтобы увидеть, займет всего минуту. - person jemiloii; 23.05.2019
comment
@AnduAndrici Да, было хорошее обновление для Array.isArray () в Chrome. Второй по скорости вариант сейчас. Твердый! - person jemiloii; 23.05.2019
comment
Я хотел бы ответить на вопрос @ AnduAndrici, потому что из ответа уже не ясно, какое решение здесь является наиболее эффективным. - person Sebastian Gaweda; 17.07.2019
comment
это ясно @SebastianGaweda, прочтите ответ. variable.constructor === Array Если бы это было не так, я бы обновил его и указал причину, по которой я обновился. - person jemiloii; 31.07.2019
comment
Отличный ответ. Спасибо. - person Anjana Silva; 11.12.2019
comment
так много правок делают ваш ответ нечитаемым. Вот почему я голосую против ... - person Clint Eastwood; 27.01.2020
comment
Все хорошо, мне нравится наблюдать, как javascript обновляется с годами. - person jemiloii; 28.01.2020
comment
Если вы собираетесь отредактировать свой ответ, подумайте о том, чтобы сделать его более читабельным для тех, кто не читал его раньше. - person AtilioA; 11.06.2020

Вы также можете использовать:

if (value instanceof Array) {
  alert('value is Array!');
} else {
  alert('Not an array');
}

Мне это кажется довольно изящным решением, но каждому свое.

Редактировать:

Начиная с ES5 теперь также:

Array.isArray(value);

Но это не работает в старых браузерах, если вы не используете полифиллы (в основном ... IE8 или аналогичные).

person Brett Bender    schedule 20.04.2009
comment
Я предлагаю на самом деле настаивать на использовании этого оператора instanceof, если вы не работаете с несколькими кадрами. Это правильный способ проверки типа объекта. - person BYK; 20.04.2009
comment
Единственный случай, когда это не удастся, - это если вы пытались протестировать массив или объект с Array instanceof Object == true. - person Pierre; 29.11.2012
comment
Если вы используете jQuery для передачи элементов с помощью find ('code') или чего-то подобного, вы можете проверить переменную с помощью variable instanceof Object, поскольку она не является экземпляром массива. - person tuck; 01.05.2013
comment
Чтобы усилить точку зрения @ BYK, это работает только с объектами в одном кадре. Не полагайтесь на это, если вы работаете с несколькими кадрами! - person Cory Klein; 25.09.2013
comment
Не работает в некоторых случаях: Array.prototype instanceof Array; // false (должно быть верно); также ({ __proto__ : Array.prototype }) instanceof Array; // true (должно быть ложным) - person vortexwolf; 04.11.2013
comment
Я плохо разбираюсь во внутреннем устройстве JS - должен ли тип прототипа совпадать с типом объекта? - person Brett Bender; 04.11.2013
comment
@BrettBender Если вы все еще активны, не могли бы вы обновить свой ответ, чтобы отразить, что с ES5 у нас есть Array.isArray? - person Nobbynob Littlun; 22.05.2014
comment
@AndrewK см. ответ Фелы Винкельмолен, в котором есть метод Array.isArray. Что касается этого ответа, вероятно, не лучшая идея преобразовать ответ в другой ответ путем редактирования. - person muffin; 25.08.2014
comment
Или, если вас не интересуют старые браузеры, вы можете использовать Array.isArray(arr) - person Dominic; 13.10.2014
comment
Это хорошо, но используйте variable.constructor === Array, это самый быстрый метод в javascript. jsperf.com/instanceof-array-vs-array-isarray - person jemiloii; 29.10.2014
comment
@muffin: почему лучше оставить ответ устаревшим на пять лет? Как вы знаете, многие пользователи не будут читать комментарии под ответом (как бы мы ни хотели), не говоря уже о том, что некоторые из этих комментариев скрыты в разделе «Показать еще». - person Dan Dascalescu; 04.12.2014
comment
@DanDascalescu Вы правы, что хранить ценную информацию под землей - нехорошо. Но я считаю неуместным изменять чей-то ответ до такой степени, чтобы он больше не оставался прежним ответом по сути. Возможно, добавление строки уведомления / FYI, отредактированной в ответ, получивший наибольшее количество голосов, будет полезным способом, который не нарушит целостность исходного ответа, но если это указанное средство, система должна включить его на том же уровне, что и голосование по и принятие ответов. В любом случае, я больше не просматриваю мета: я не помню, что (в моем понимании) консенсус относительно целостности ответа. - person muffin; 04.12.2014
comment
Это правильно, поскольку он также будет обрабатывать, если значение не определено или равно нулю. - person James Nurse; 12.08.2015

Есть несколько решений со своими причудами. Эта страница дает хороший обзор . Одно из возможных решений:

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}
person Peter Smit    schedule 20.04.2009
comment
Если вы внимательно прочитаете, в нем говорится, что этот метод необходим, когда вы работаете с многокадровыми документами, что не рекомендуется. Этот метод можно легко исправить при небольшом изменении функции toString. - person BYK; 20.04.2009
comment
Поэтому ссылка дается, чтобы Бретт мог проверить их и посмотреть, в каком случае его функция должна работать. - person Peter Smit; 20.04.2009
comment
Смотрите мой ответ ниже. Я рекомендую способ Питера Смита. - person Brian; 29.06.2012
comment
Этот метод рекомендован Mozilla. . - person Hank; 28.05.2015

Я заметил, что кто-то упомянул jQuery, но я не знал, что существует функция isArray(). Оказывается, он был добавлен в версии 1.3.

jQuery реализует это, как предлагает Питер:

isArray: function( obj ) {
    return toString.call(obj) === "[object Array]";
},

Уже поверив jQuery (особенно их методам кроссбраузерной совместимости), я либо обновлюсь до версии 1.3 и воспользуюсь их функцией (при условии, что обновление не вызовет слишком много проблем), либо воспользуюсь этим предложенным методом непосредственно в моем код.

Большое спасибо за предложения.

person Andy McCluggage    schedule 20.04.2009
comment
См. эту статью для хорошее обсуждение темы. Вывод - использовать это решение. - person Nick G.; 12.03.2014
comment
Это дает мне ошибку SCRIPT65535 в IE10. - person polm23; 27.05.2014

В современных браузерах (и некоторых устаревших браузерах) вы можете делать

Array.isArray(obj)

(Поддерживается Chrome 5, Firefox 4.0, IE 9, Opera 10.5 и Safari 5)

Если вам нужна поддержка более старых версий IE, вы можете использовать es5-shim для полифил-массива .isArray; или добавьте следующее

# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }
};

Если вы используете jQuery, вы можете использовать jQuery.isArray(obj) или $.isArray(obj). Если вы используете подчеркивание, вы можете использовать _.isArray(obj)

Если вам не нужно обнаруживать массивы, созданные в разных фреймах, вы также можете просто использовать instanceof

obj instanceof Array

Примечание: ключевое слово arguments, которое может использоваться для доступа к аргументу функции, не является массивом, хотя (обычно) ведет себя как массив:

var func = function() {
  console.log(arguments)        // [1, 2, 3]
  console.log(arguments.length) // 3
  console.log(Array.isArray(arguments)) // false !!!
  console.log(arguments.slice)  // undefined (Array.prototype methods not available)
  console.log([3,4,5].slice)    // function slice() { [native code] } 
}
func(1, 2, 3)

person Fela    schedule 08.01.2014
comment
Это, наверное, лучший из самых современных подходов. Я видел это вместе с полифилом в MDN, так что это означает, что Mozilla доверяет ему developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person John; 12.04.2014
comment
Разве вы там не пропали prototype? Кажется, должно быть Object.prototype.toString.call. - person Brock; 20.11.2014

Это старый вопрос, но, столкнувшись с той же проблемой, я нашел очень элегантное решение, которым хочу поделиться.

Добавление прототипа в массив делает его очень простым

Array.prototype.isArray = true;

Теперь, если у вас есть объект, который вы хотите протестировать, чтобы увидеть, является ли его массив, все, что вам нужно, это проверить новое свойство

var box = doSomething();

if (box.isArray) {
    // do something
}

isArray доступен, только если это массив

person Ibu    schedule 24.10.2011
comment
для меня это звучит так круто! это могло быть родным. Кстати, он работает, даже если массив был создан до прототипирования? - person Vitim.us; 12.11.2011
comment
@Vitimtk Прототип действует как резерв для фактического объекта, поэтому это должно работать, даже если рассматриваемый массив уже существует. Конечно, это не сработает, пока не будет обработана исходная строка. - person Markus Bruckner; 28.12.2011
comment
Предполагая, что никто не делает Object.prototype.isArray = true;! :( - person ErikE; 30.09.2012
comment
Обратите внимание, что в ES5 Array.isArray - это метод (например, Array.isArray([1,2,3]) === true), поэтому @ErikE не был троллем. Я бы не стал следовать этому ответу, поскольку он нарушит код в некоторых современных браузерах. - person JaredMcAteer; 11.07.2013
comment
@JaredMcAteer ваш пример правильный. Однако ErikE не связан, Array! = [1,2,3]. Таким образом, вы все еще можете сделать [1,2,3] .isArray === true с моим решением - person Ibu; 11.07.2013
comment
@Ibu, и ты можешь сделать {}.isArray === true с моим решением, в этом весь смысл ... - person ErikE; 12.07.2013
comment
На мой взгляд, изменение прототипа типов данных - плохая практика. - person BentOnCoding; 24.09.2014
comment
@BentOnCoding насчет Array.prototype["com.my.unique.name"].isArray;) - person SOFe; 28.12.2018

Через Crockford:

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (value instanceof Array) {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

Основной недостаток, о котором упоминает Крокфорд, - это неспособность правильно определять массивы, которые были созданы в другом контексте, например window. На этой странице есть гораздо более сложная версия, если этого недостаточно.

person Hank Gay    schedule 20.04.2009

Если вы имеете дело только с EcmaScript 5 и выше, вы можете использовать встроенную функцию Array.isArray

e.g.,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false
person JaredMcAteer    schedule 11.07.2013

Мне лично нравится предложение Питера: https://stackoverflow.com/a/767499/414784 (для ECMAScript 3. Для ECMAScript 5, используйте Array.isArray())

Однако комментарии к сообщению указывают на то, что если toString() вообще изменится, этот способ проверки массива не удастся. Если вы действительно хотите быть конкретным и убедиться, что toString() не был изменен, и нет проблем с атрибутом класса объектов ([object Array] - это атрибут класса объекта, который является массивом), я рекомендую сделать что-то вроде этого:

//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')
    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    }
    else
    {
        // may want to change return value to something more desirable
        return -1; 
    }
}

Обратите внимание, что в JavaScript The Definitive Guide 6-е издание, 7.10 говорится, что Array.isArray() реализован с использованием Object.prototype.toString.call() в ECMAScript 5. Также обратите внимание, что если вы собираетесь беспокоиться об изменении реализации toString(), вам также следует беспокоиться об изменении любого другого встроенного метода. . Зачем использовать push()? Кто-то может это изменить! Такой подход глупый. Вышеупомянутая проверка - это предлагаемое решение для тех, кто беспокоится о toString() изменениях, но я считаю, что в этой проверке нет необходимости.

person Brian    schedule 03.12.2011
comment
Хороший вызов по стандарту ECMAScript 5. Конечно, вы не можете гарантировать, что браузер поддерживает это, но это должен быть первый способ проверить новый код. - person styfle; 14.12.2012
comment
Начну с того, что это немного выше моей головы. Однако будет ли такой тест более надежным ?: return Object.prototype.toString.call(o) === Object.prototype.toString.call([]); - person Grant Lindsay; 24.06.2014

Когда я разместил этот вопрос, версия JQuery, которую я использовал, не включала функцию isArray. Если бы это было так, я бы, вероятно, просто использовал его, полагая, что эта реализация является лучшим независимым от браузера способом выполнить эту конкретную проверку типа.

Поскольку JQuery теперь предлагает эту функцию, я бы всегда ее использовал ...

$.isArray(obj);

(начиная с версии 1.6.2) Он по-прежнему реализуется с использованием сравнений строк в форме

toString.call(obj) === "[object Array]"
person Andy McCluggage    schedule 08.08.2011

Подумал, что добавлю еще один вариант для тех, кто, возможно, уже использует библиотеку Underscore.js в своем скрипте. Underscore.js имеет функцию isArray () (см. http://underscorejs.org/#isArray).

_.isArray(object) 

Возвращает истину, если объект является массивом.

person Benjen    schedule 16.03.2012
comment
В реализации js подчеркивания используется собственный Array.isArray, если он доступен, в противном случае - метод toString. - person Kris; 24.04.2014
comment
Такая же функция присутствует в Lodash - person Jundiaius; 13.04.2016

Если вы используете Angular, вы можете использовать функцию angular.isArray ()

var myArray = [];
angular.isArray(myArray); // returns true

var myObj = {};
angular.isArray(myObj); //returns false

http://docs.angularjs.org/api/ng/function/angular.isArray

person joseph.l.hunsaker    schedule 19.03.2014
comment
Вы также можете использовать не специфичные для Angular браузеры, но только IE9 + и все стандартные браузеры: ‹pre› ‹code› Array.isArray (myArray); // возвращает истину Array.isArray (myObj); // возвращает false ‹/code› ‹/pre› - person PDA; 17.07.2014

В JavaScript The Good Parts Крокфорда есть функция, проверяющая, является ли данный аргумент массивом:

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

Он объясняет:

Во-первых, мы спрашиваем, истинно ли значение. Мы делаем это, чтобы отклонить нулевые и другие ложные значения. Во-вторых, мы спрашиваем, является ли значение typeof «объектом». Это будет верно для объектов, массивов и (как ни странно) null. В-третьих, мы спрашиваем, имеет ли значение свойство длины, которое является числом. Это всегда будет верно для массивов, но обычно не для объектов. В-четвертых, мы спрашиваем, содержит ли значение метод сращивания. Это снова будет верно для всех массивов. Наконец, мы спрашиваем, является ли свойство length перечислимым (будет ли длина создаваться циклом for in?). Это будет неверно для всех массивов. Это самый надежный тест на массивность, который я нашел. Очень жаль, что это так сложно.

person Yunzhou    schedule 03.12.2013
comment
И это были только хорошие стороны. Представьте, когда будет опубликован JavaScript The Bad Parts ... - person FrancescoMM; 30.01.2017

Универсальное решение представлено ниже:

Object.prototype.toString.call(obj)=='[object Array]'

Начиная с ECMAScript 5 формальное решение:

Array.isArray(arr)

Кроме того, для старых библиотек JavaScript вы можете найти решение ниже, хотя оно недостаточно точное:

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

Решения взяты из http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript

person PixelsTech    schedule 11.01.2015

код, указанный на странице https://github.com/miksago/Evan.js/blob/master/src/evan.js.

  var isArray = Array.isArray || function(obj) {
    return !!(obj && obj.concat && obj.unshift && !obj.callee);};
person didxga    schedule 26.05.2011
comment
Почему вы проверяете и concat, и unshift, этого недостаточно для проверки на unshift? - person Marco Demaio; 18.02.2014
comment
Чем больше методов мы проверяем, имеет ли Array перемещение, скорее всего, это действительно массив. Другие объекты могут иметь concat или unshift, но менее вероятно, что они оба. - person Kris; 24.04.2014

Я использовал эту строку кода:

if (variable.push) {
   // variable is array, since AMAIK only arrays have push() method.
}
person Saeed Neamati    schedule 06.01.2013
comment
Это совсем не лучшее решение. В этом решении любой объект с истинным свойством push будет считаться массивом. - person teleclimber; 28.04.2014

Для тех, кто кодирует гольф, ненадежный тест с наименьшим количеством символов:

function isArray(a) {
  return a.map;
}

Это обычно используется при обходе / выравнивании иерархии:

function golf(a) {
  return a.map?[].concat.apply([],a.map(golf)):a;
}

input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
person Joe Frambach    schedule 24.10.2013

Из w3schools:

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
person Jahid    schedule 29.03.2015

Мне понравился ответ Брайана:

function is_array(o){
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    } else{
        // may want to change return value to something more desirable
        return -1; 
    }
}

но вы могли бы сделать так:

return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
person zeageorge    schedule 20.04.2013

Я создал этот небольшой фрагмент кода, который может возвращать истинные типы.

Я пока не уверен в производительности, но это попытка правильно определить тип.

https://github.com/valtido/better-typeOf также немного писал об этом здесь http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof/

он работает аналогично текущему типу.

var user = [1,2,3]
typeOf(user); //[object Array]

Он думает, что может потребоваться небольшая тонкая настройка, и принимает во внимание вещи, которые я не встречал и не тестировал должным образом. так что дальнейшие улучшения приветствуются, будь то производительность или неправильный перенос typeOf.

person Val    schedule 28.07.2014

Я думаю, что лучше всего использовать myObj.constructor == Object и myArray.constructor == Array. Это почти в 20 раз быстрее, чем при использовании toString (). Если вы расширяете объекты своими собственными конструкторами и хотите, чтобы эти творения также считались «объектами», это не сработает, но в остальном все будет быстрее. typeof работает так же быстро, как и метод конструктора, но typeof [] == 'object' возвращает true, что часто бывает нежелательно. http://jsperf.com/constructor-vs-tostring

Следует отметить, что null.constructor выдаст ошибку, поэтому, если вы можете проверять нулевые значения, вам сначала придется выполнить if (testThing! == null) {}

person user1585789    schedule 24.08.2014

Поскольку свойство .length специально для массивов в javascript, вы можете просто сказать

obj.length === +obj.length // true if obj is an array

Underscorejs и несколько других библиотек используют этот короткий и простой трюк.

person TypingTurtle    schedule 02.03.2014
comment
Не могли бы вы объяснить, как это работает? В основном, что делает "+"? - person Andy McCluggage; 03.03.2014
comment
Это хорошо, но также верно, когда объект является функцией или строкой, а также любым другим объектом с длиной свойства, равной номеру типа. Почему? Ну, унарный оператор + фактически преобразует переменную в число. Итак, в основном они проверяют, является ли obj.length числом. [Объект Object] не имеет длины свойства, он не определен, поэтому, когда вы приводите undefined как число, оно становится NaN, вышеуказанная проверка оказывается ложной. Таким образом, он возвращает истину, если длина свойства объекта является числом, что в случае массивов, строк и функций будет истинным. Underscore должен делать больше, чем просто это. - person John; 12.04.2014

Я только что придумал:

if (item.length) //This is an array else //not an array

person trololol    schedule 12.02.2015
comment
var item = 'this_is_not_an_array'; - person kev; 06.03.2015
comment
Плохое решение! У струны тоже есть длина. - person pmrotule; 09.03.2015
comment
На самом деле строка представляет собой массив символов, поэтому, по сути, это работает - person Shingala94; 13.03.2015
comment
@PatrickNijhuis - строка является примитивным типом в javascript, а массив - объект. На обычном языке вы правы - строка - это массив символов, - но в javascript это утверждение неверно. Это важное различие и причина, по которой это плохой ответ. - person wahwahwah; 27.03.2015
comment
Нет, массив нулевой длины по-прежнему является массивом. - person Dave Burton; 14.08.2016
comment
вы можете поставить typeof item == 'object', и ответ может быть приемлемым - person Abz Rockers; 31.08.2017
comment
что еще более важно: пустой массив не пройдет этот тест, потому что 0 - ложь - person David Schumann; 26.03.2020