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

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

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

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

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

1593
задан 20 апр. '09 в 12:02
источник поделиться
24 ответов

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

variable.constructor === Array

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

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

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

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

variable instanceof Array

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

Array.isArray(variable)

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

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

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

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

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

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

1468
ответ дан 29 окт. '14 в 18:07
источник

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

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

Мне кажется, это довольно элегантное решение, но для каждого из них.

Изменить:

В ES5 теперь также есть:

Array.isArray(value);

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

1007
ответ дан 20 апр. '09 в 12:05
источник

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

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

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

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

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

73
ответ дан 20 апр. '09 в 13:10
источник

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

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}
71
ответ дан 20 апр. '09 в 12:08
источник

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

Array.isArray(obj)

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

Если вам необходимо поддерживать старые версии IE, вы можете использовать ES5-подкладку к polyfill Array.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)
59
ответ дан 08 янв. '14 в 10:37
источник

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

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

Array.prototype.isArray = true;

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

var box = doSomething();

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

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

53
ответ дан 25 окт. '11 в 0:12
источник

Через 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. Эта страница имеет гораздо более сложную версию, если этого недостаточно.

45
ответ дан 20 апр. '09 в 12:07
источник

Мне лично нравится предложение Питера: qaru.site/questions/990/... (для 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 an array
//returns false if it passes test and it 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. Окончательное руководство. 6-е издание, 7.10, говорит, что Array.isArray() реализуется с использованием Object.prototype.toString.call() в ECMAScript 5. Также обратите внимание, что если вы собираетесь беспокоиться о смене реализации toString(), вам также следует беспокойство о каждом другом встроенном методе тоже. Зачем использовать push()? Кто-то может это изменить! Такой подход глуп. Вышеупомянутая проверка является предлагаемым решением для тех, кто обеспокоен изменением toString(), но я считаю, что проверка не нужна.

26
ответ дан 03 дек. '11 в 6:17
источник

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

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

$.isArray(obj);

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

toString.call(obj) === "[object Array]"
19
ответ дан 08 авг. '11 в 17:42
источник

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

например,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false
16
ответ дан 11 июля '13 в 17:05
источник

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

_.isArray(object) 

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

16
ответ дан 16 марта '12 в 10:50
источник

Если вы используете 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

10
ответ дан 19 марта '14 в 11:40
источник

В Crockford JavaScript Хорошие части существует функция проверки, является ли данный аргумент массивом:

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

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

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

9
ответ дан 03 дек. '13 в 6:44
источник

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

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

5
ответ дан 11 янв. '15 в 17:17
источник

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

if (variable.push) {
   // variable is array, since AMAIK only arrays have push() method.
}
4
ответ дан 06 янв. '13 в 11:01
источник

упомянутый 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);};
3
ответ дан 26 мая '11 в 16:08
источник

Из w3schools:

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
2
ответ дан 29 марта '15 в 16:07
источник

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

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]
2
ответ дан 24 окт. '13 в 21:43
источник

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

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([]);
1
ответ дан 20 апр. '13 в 20:17
источник

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

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

1
ответ дан 24 авг. '14 в 23:32
источник

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

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

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.

1
ответ дан 28 июля '14 в 12:32
источник
function isArray(x){
    return ((x != null) && (typeof x.push != "undefined"));
}
-3
ответ дан 13 марта '13 в 10:12
источник

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

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

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

-5
ответ дан 02 марта '14 в 21:01
источник

Что-то, с чем я только что придумал:

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

-16
ответ дан 13 февр. '15 в 2:01
источник

Другие вопросы по меткам или Задайте вопрос