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

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

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


Я рассмотрел различные решения ниже и создал тест jsperf.

+2470
23 янв. '11 в 18:53
источник поделиться
46 ответов
  • 1
  • 2

В современных браузерах вы можете сделать

Array.isArray(obj)

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

Для обратной совместимости вы можете добавить следующие

# 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
+690
06 янв. '14 в 18:11
источник

Связанные вопросы


Похожие вопросы

Метод, указанный в стандарте ECMAScript для поиска класса Object, заключается в использовании метода toString из Object.prototype.

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

Или вы можете использовать typeof для проверки, является ли это строкой:

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

Или, если вас не интересует производительность, вы можете просто сделать concat для нового пустого массива.

someVar = [].concat( someVar );

Там также конструктор, который вы можете запросить напрямую:

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

Ознакомьтесь с подробным описанием блога @TJ Crowder, опубликованным в его комментарии ниже.

Ознакомьтесь с этим эталоном, чтобы получить представление о том, какой метод работает лучше: http://jsben.ch/#/QgYAV

Из @Bharath конвертировать строку в массив с использованием Es6 для заданного вопроса:

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

предположим:

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']
+1905
23 янв. '11 в 18:54
источник

Я бы сначала проверил, поддерживает ли ваша реализация isArray:

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

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

v instanceof Array
+1246
23 янв. '11 в 18:55
источник

jQuery также предлагает метод $.isArray():

var a = ["A", "AA", "AAA"];

if($.isArray(a)) {
  alert("a is an array!");
} else {
  alert("a is not an array!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
+289
02 апр. '12 в 12:15
источник

Это самый быстрый среди всех методов (поддерживаются все браузеры):

function isArray(obj){
    return !!obj && obj.constructor === Array;
}
+97
06 дек. '15 в 10:12
источник

Представьте, что у вас есть этот массив ниже:

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

Javascript (новые и старые браузеры):

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

или

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

или

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

затем назовите его так:

isArray(arr);

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

Array.isArray(arr);

JQuery:

$.isArray(arr);

Угловой:

angular.isArray(arr);

Подчеркивание и Lodash:

_.isArray(arr);
+37
27 дек. '16 в 13:17
источник

Array.isArray работает быстро, но не поддерживается всеми версиями браузеров. Таким образом, вы можете сделать исключение для других и использовать универсальный метод:

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }
+32
10 дек. '12 в 17:01
источник

Простая функция для проверки:

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}
+22
04 сент. '12 в 17:56
источник

Вы можете попробовать этот подход: http://web.archive.org/web/20100424091244/http://www.ajaxdr.com/code/javascript-version-of-phps-is_array-function/

EDIT: также, если вы уже используете JQuery в своем проекте, вы можете использовать его функцию $. isArray().

+16
23 янв. '11 в 18:56
источник

Поскольку MDN говорит здесь:

используйте Array.isArray или Object.prototype.toString.call, чтобы различать регулярные объекты из массивов

Вот так:

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

  • Array.isArray(arr)

+15
14 сент. '12 в 21:02
источник

Только одно линейное решение для этого вопроса

x instanceof Array

где x - это переменная, она вернет true, если x - массив, а false - если нет.

+15
08 июн. '17 в 12:48
источник

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

var myArray=[];

if(myArray instanceof Array)
{
....
}
+13
15 янв. '13 в 8:58
источник

Я бы сделал функцию для проверки типа объекта, с которым вы имеете дело...

function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }

// tests
console.log(
  whatAmI(["aiming","@"]),
  whatAmI({living:4,breathing:4}),
  whatAmI(function(ing){ return ing+" to the global window" }),
  whatAmI("going to do with you?")
);

// output: Array Object Function String

тогда вы можете написать простую инструкцию if...

if(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}
+13
08 авг. '12 в 13:34
источник

Я делаю это очень просто. Работает на меня. Любые недостатки?

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)
+11
04 апр. '15 в 6:58
источник

Это моя попытка улучшить этот ответ с учетом комментариев:

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

Он избавляется от if/else и учитывает возможность того, что массив равен null или undefined

+11
01 апр. '15 в 20:35
источник

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]";
};
+10
05 мар. '13 в 8:26
источник

Я обновил скрипт jsperf с помощью двух альтернативных методов, а также проверки ошибок.

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

/* Initialisation */
Object.prototype.isArray = function() {
  return false;
};
Array.prototype.isArray = function() {
  return true;
};
Object.prototype._isArray = false;
Array.prototype._isArray = true;

var arr = ["1", "2"];
var noarr = "1";

/* Method 1 (function) */
if (arr.isArray()) document.write("arr is an array according to function<br/>");
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");
/* Method 2 (value) - **** FASTEST ***** */
if (arr._isArray) document.write("arr is an array according to member value<br/>");
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");

Эти два метода не работают, если переменная принимает значение undefined, но они работают, если вы уверены, что они имеют значение. Что касается проверки с учетом производительности, если значение представляет собой массив или одно значение, второй метод выглядит как действительный быстрый метод. Он немного быстрее, чем "экземпляр" в Chrome, в два раза быстрее, чем второй лучший метод в Internet Explorer, Opera и Safari (на моей машине).

+10
01 авг. '15 в 11:10
источник

Я знаю, что люди ищут какой-то грубый подход к JavaScript. Но если вы хотите меньше думать, посмотрите здесь: http://underscorejs.org/#isArray

_.isArray(object) 

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

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
+9
04 апр. '12 в 0:46
источник

Лучшее решение, которое я видел, это кросс-браузерная замена для typeof. Проверьте решение Angus Croll здесь.

Версия TL; DR приведена ниже, но статья - отличное обсуждение проблемы, поэтому вы должны ее прочитать, если у вас есть время.

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 */};
+5
23 мар. '12 в 17:07
источник

Самый простой и быстрый способ проверить, является ли объект массивом или нет.

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

или

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

или вы можете сделать служебную функцию:

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

использование:

isArray(arr); //return true
+5
01 мар. '17 в 9:25
источник

Вот мой ленивый подход:

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

// ...

var test = [],
    wat = {};

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

Я знаю, что это святотатство "запутаться" с прототипом, но он выглядит значительно лучше, чем рекомендуемый метод toString.

Примечание. Ловушка этого подхода заключается в том, что не работает через границы iframe, но для моего это не проблема.

+5
11 янв. '13 в 8:56
источник

В книге Стояна Стефанова есть хороший пример JavaScript Patterns, который предполагает обработку всех возможных проблем, а также использует метод Array.isArray() ECMAScript 5.

Итак, вот оно:

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

Кстати, если вы используете jQuery, вы можете использовать его метод $.isArray()

+5
15 дек. '13 в 7:11
источник

Вы можете использовать метод isArray, но я бы предпочел проверить

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

+5
28 февр. '18 в 17:21
источник

Можно использовать следующее, если вы знаете, что у вашего объекта нет метода concat.

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It an array");
}
+5
24 авг. '16 в 8:02
источник

Если только два типа значений, которые могут быть переданы этой функции, являются строкой или массивом строк, сохраняйте ее просто и используйте проверку typeof для возможности строки:

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}
+4
23 янв. '11 в 19:51
источник

Вы можете попробовать следующее:

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

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

obj.constructor.prototype.hasOwnProperty('push') // false
+4
25 февр. '16 в 5:52
источник
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))
+4
29 окт. '13 в 21:26
источник

Простая функция для проверки, является ли входное значение массивом следующим:

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

Это работает как кросс-браузер, так и старые браузеры. Это извлечено из T.J. Сообщение блога Броунов

+4
02 февр. '14 в 0:29
источник

Эта функция превратит почти что-нибудь в массив:

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]"
}

Он использует некоторые новые функции браузера, поэтому вы можете захотеть polyfill для максимальной поддержки.

Примеры:

> 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. строки будут преобразованы в массив с одним элементом, а не с массивом символов. Удалите проверку isString, если вы предпочтете ее наоборот.

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

+4
24 окт. '16 в 15:48
источник

В вашем случае вы можете использовать метод concat Array, который может принимать как отдельные объекты, так и массив (и даже комбинированные ):

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 кажется одним из старейших методов Array (даже IE 5.5 хорошо это знает).

+4
15 сент. '17 в 9:41
источник
  • 1
  • 2

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