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

2336

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

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


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

  • 6
    Я думал, что вы хотели проверить, является ли объект массивом, но вы хотите проверить, является ли объект массивом строк или единственной строкой. Не уверены, что видите это? Или это только у меня так? Я думал о чем - то большем , как это ... я один - то здесь отсутствует?
  • 129
    TL; DR - arr.constructor === Array самый быстрый.
Показать ещё 10 комментариев
Теги:
arrays
javascript-objects

43 ответа

534
Лучший ответ

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

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
  • 6
    Вот более полный список браузеров, которые поддерживают Array.isArray
  • 0
    if (typeof Array.isArray === 'undefined') { можно изменить на if(!Array.isArray) {
Показать ещё 3 комментария
1984

Метод, указанный в стандарте 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']
  • 63
    +1 Да, toString - один из способов пойти. Я делаю небольшую сводку здесь: blog.niftysnippets.org/2010/09/say-what.html
  • 0
    Это работает и на Titanium.
Показать ещё 28 комментариев
1298

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

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

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

v instanceof Array
  • 124
    v instanceof Array вернет false, если v был создан в другом фрейме ( v является экземпляром класса thatFrame.contentWindow.Array ).
  • 45
    В частности: Array.isArray определен как часть ECMAScript 5 / Javascript 1.8.5.
Показать ещё 9 комментариев
273

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>
  • 16
    Для справки: api.jquery.com/jQuery.isArray
  • 27
    Просто обратите внимание, jQuery использует метод toString для внутреннего использования: GitHub Source
Показать ещё 4 комментария
95

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

function isArray(obj){
    return !!obj && obj.constructor === Array;
}
  • 2
    Вы правы, это самый быстрый результат по тестам, которые я включил в вопрос.
  • 4
    Есть ли недостатки в использовании этого метода? Это кажется намного более простым и эффективным, чем принятый, лучший ответ.
Показать ещё 8 комментариев
36

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

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);
32

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

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }
  • 3
    Вам необходимо получить метод .toString() из Object.prototype . Прямо сейчас вы используете window.toString() , что не то же самое.
  • 0
    Вы правы. window.toString делает то же самое, что Object.prototype.toString только в Chrome.
Показать ещё 2 комментария
20

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

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}
  • 14
    Я бы сократил это до одной строки return object.constructor === Array - но вы уверены, что это вернет true только для массивов?
  • 12
    Можно сделать это со всеми логическими выражениями. Сводит меня с ума, когда я вижу, if(x) return true; else return false :-) Даже если это в обратном порядке, вы должны отрицать выражение.
Показать ещё 8 комментариев
16

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

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

13

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

x instanceof Array

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

  • 0
    Гораздо чище и в будущем безопасно! Это или typeof сравнения.
  • 0
    Это то, что получает хорошую поддержку браузера? Мне это нравится.
Показать ещё 1 комментарий
13

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

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

Вот так:

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

  • Array.isArray(arr)

12

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

var myArray=[];

if(myArray instanceof Array)
{
....
}
  • 1
    Несколько человек уже упомянули instanceof . Я думаю, что это терпит неудачу в нескольких странных сценариях.
12

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

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
}
10

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

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)
  • 7
    одураченный {isArray:true}
  • 0
    JSON.parse(someDataFromElsewhere).items.isArray может вернуть true (в зависимости от данных) и нарушить ваш код.
10

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

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

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

  • 0
    конструктор недоступен в ES5
  • 0
    @TechTurtle Вы уверены? Этот код работает в ES6
9

Я обновил скрипт 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 (на моей машине).

9

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

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

_.isArray(object) 

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

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
  • 6
    «Если не включен еще один тег для фреймворка / библиотеки, ожидается чистый ответ JavaScript».
5

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

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

  • 0
    Почему вы предпочитаете это?
  • 0
    @mpen Object.getPrototypeOf(yourvariable) возвращает прототип объекта Array. И код является самым быстрым и безопасным, чтобы на него можно было положиться.
Показать ещё 1 комментарий
5

В книге Стояна Стефанова есть хороший пример 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()

  • 2
    +1: почему бы не просто if(!Array.isArray) {... ?
5

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

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, но для моего это не проблема.

  • 0
    Работает ли на IE8 32 бит и 64 бит.
  • 0
    это не лучше с точки зрения производительности, по крайней мере на FF30 на Ubuntu 64-bit
Показать ещё 6 комментариев
5

Лучшее решение, которое я видел, это кросс-браузерная замена для 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 */};
4

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

 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
4

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

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

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

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It an array");
}
  • 0
    Это хороший трюк, но его можно переопределить ... но в большинстве случаев следует получить результат
4

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

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

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

4
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

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

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}
  • 0
    Да ... это сработало бы для этого сценария, но не в целом. Все равно закончилось использованием varargs. :)
3

К счастью, ECMA 5 представила Array.isArray() еще в декабре 2009 года. Если по какой-то причине вы используете версию JavaScript старше ECMA 5, обновите ее.

Однако, если вы настаиваете на этом, массивы имеют определенные свойства, которые отличает их от любого другого типа. Свойства, которые я не видел в других ответах. Давайте перейдем к политике JavaScript.

Массив - это объект (typeof [] === "object"), но в отличие от традиционных объектов они имеют свойство length (typeof ( {}).length === "undefined"). null также является объектом (typeof null === "object"), но вы не можете получить доступ к свойству null поскольку null не является объектом. Это ошибка в спецификации, которая полностью возвращается к самому началу JavaScript, когда объекты имеют тег типа 0 а null был представлен как буквальный нулевой указатель 0x00, что заставляло интерпретатор путать его с объектами.

К сожалению, это не учитывает [] vs {length:0}. Поэтому мы должны перейти к цепочке прототипов.

( []).__proto__ === Array.prototype && ( []).__proto__ !== Object.prototype.

Таким образом, без Array.isArray(), это примерно то самое ближайшее, что мы можем получить:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && array.__proto__ === Array.prototype;
}

[ [], [1,2,3], {length: 0}, {},
  1, 0, Infinity, NaN, "1", "[1,2,3]",
  null, undefined, [null], [undefined], {a:[]},
  [{}], [{length: 0}], [Infinity], [NaN],
  {__proto__: Array.prototype}
].filter(is_array)
// Expected: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN] ]
// Actual:   [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN], {__proto__: Array.prototype} ]

Объект, злонамеренно предназначенный для того, чтобы выглядеть так же, как массив, фактически проходит тест turing. Однако заменить цепочку прототипов цепочкой прототипов Array достаточно, чтобы заставить ее действовать точно так же, как массив, эффективно создавая массив. Единственная вещь в мире, которая может Array.isArray() такой объект, на самом деле не является массивом, это Array.isArray(). Но для целей, которые вы обычно проверяете, является ли объект массивом, этот объект должен хорошо сочетаться с вашим кодом. Даже поведение, когда вы изменяете длину массива искусственно, одинаково: если длина больше, чем количество элементов в массиве, у вас будут "пустые слоты" этого специального "неявного неопределенного" типа, который как-то отличается от undefined, а также === undefined; тот же тип, который является причиной того, что мы используем typeof obj !== "undefined" чтобы избежать метаданных ReferenceError поскольку obj === undefined только не выдает ошибку, если obj явно определен как undefined.

a = {__proto__: Array.prototype}; // Array {}
a.push(5)
a // [5]
a.length = 5
a // [5, empty x 4]
b = a.map(n => n*n) // [25, empty x 4]
b.push(undefined)
b.push(undefined)
b // [25, empty x 4, undefined, undefined]
b[1] // undefined
b[1] === b[5] // true
Array.isArray(a) // false
Array.isArray(b) // true

Однако не используйте is_array(). Одно дело - изобретать колесо для обучения. Это еще одна вещь, чтобы сделать это в производственном коде. Даже не используйте его как полипол. Поддержка старых версий JS означает поддержку старых браузеров, что означает поощрение использования небезопасного программного обеспечения, что позволяет подвергнуть пользователя опасности для вредоносного ПО.

3

В вашем случае вы можете использовать метод 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 хорошо это знает).

3

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

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

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

obj.constructor.prototype.hasOwnProperty('push') // false
  • 0
    Есть много простых способов сделать это!
3
A = [1,2,3]
console.log(A.map==[].map)

В поисках кратчайшей версии вот что я получил до сих пор.

Обратите внимание, что нет идеальной функции, которая всегда будет обнаруживать все возможные комбинации. Лучше знать все возможности и ограничения ваших инструментов, чем ожидать волшебный инструмент.

  • 1
    Небольшое происхождение моего A.map !== undefined но да, это может быть скользкой дорогой в мире обезьяньих патчеров;)
  • 0
    К вашему сведению: это не работает в iFrames ( stackoverflow.com/questions/460256/… )
1

Другие методы также существуют для проверки, но я предпочитаю следующий метод, как лучше всего проверить (поскольку вы можете легко проверить типы других объектов).

> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'

Объяснение (с простыми примерами на узле REPL) "

> o = {'ok': 1}
{ ok: 1 }
> a = [1, 2]
[ 1, 2 ]
> typeof o
'object'
> typeof a
'object'
>
> Object.prototype.toString.call(o)
'[object Object]'
> Object.prototype.toString.call(a)
'[object Array]'
>

Объект или массив "

> Object.prototype.toString.call(o).slice(8,).replace(/\]$/, '')
'Object'
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>

Null или Undefined "

> Object.prototype.toString.call(undefined).slice(8,).replace(/\]$/, '')
'Undefined'
> Object.prototype.toString.call(null).slice(8,).replace(/\]$/, '')
'Null'
>

String "

> Object.prototype.toString.call('ok').slice(8,).replace(/\]$/, '')
'String'

Число "

> Object.prototype.toString.call(19).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.0).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.7).slice(8,).replace(/\]$/, '')
'Number'
>

Я ценю предложение @mpen использовать -1 вместо регулярного выражения следующим образом.

> Object.prototype.toString.call(12).slice(8,-1)
'Number'
>
> Object.prototype.toString.call(12.0).slice(8,-1)
'Number'
>
> Object.prototype.toString.call([]).slice(8,-1)
'Array'
> Object.prototype.toString.call({}).slice(8,-1)
'Object'
>
> Object.prototype.toString.call('').slice(8,-1)
'String'
>
  • 0
    Вы также можете использовать -1 как 2-й аргумент, чтобы slice и сохранить регулярное выражение для дождливого дня.
  • 0
    Спасибо @mpen . Я добавил ваши предложения.
1
var is_array = function (value) {
   return value &&
     typeof value === 'object' &&
     typeof value.length === 'number' &&
     typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

Эта функция взята из книги "JS good parts", отлично подходит для меня.

  • 0
    var object = {splice: function(){}}; Object.defineProperty(object, "length", {value: 1, enumerable: false}); console.log(is_array(object));
0

Вот фрагмент кода, который объяснит важный факт массивов, которые должны быть известны на ранних этапах изучения JS (в отличие от меня).

// this functions puts a string inside an array
var stringInsideArray = function(input) {
  if (typeof input === 'string') {
    return [input];
  }
  else if (Array.isArray(input)) {
    return input;
  } 
  else {
    throw new Error("Input is not a string!");
  }
}

var output = stringInsideArray('hello');
console.log('step one output: ', output); // ["hello"]

// use typeof method to verify output is an object
console.log('step two output: ', typeof output); // object

// use Array.isArray() method to verify output is an array
console.log('step three output: ', Array.isArray(output)); // true

Массивы, по сути, объекты.

Используя оператор typeof, вывод stringInsideArray('hello') доказывает, что ["hello"] действительно является объектом. Это сбило меня с толку дольше всего, потому что я предполагал, что массивы будут типом данных JavaScript...

Существует только 7 типов данных JS, и массивы НЕ являются одним из них.

Чтобы ответить на ваш вопрос, использование метода Array.isArray() определяет, что output являются массивом.

  • 0
    Просто FYI, [].concat(string) - это довольно странный способ написания [string] .
  • 0
    @mpen спасибо, что дали мне знать. из любопытства, как бы вы это написали?
Показать ещё 6 комментариев
0

есть разница между checkout it prototype и Array.isArray:

function isArray(obj){
    return Object.getPrototypeOf(obj) === Array.prototype
}

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

но для этого объекта Proxy:

var arr = [1,2,3]

var proxy = new Proxy(arr,{})

console.log(Array.isArray(proxy)) // true

Array.isArray примет его как массив.

  • 0
    Похоже, вы подразумеваете, что ваша функция isArray не вернет true для Proxy, но это не так; они оба возвращают true для Прокси (и непроксируемых массивов)
0

Вы также можете проверить свойство массива. Когда вы попытаетесь получить доступ к свойству length массива, он вернет число (0 для пустого массива), а если вы попытаетесь получить доступ к свойству length объекта, оно вернется не определено.

if(Object.prototype.toString.call(arrayList) === '[object Array]') {
  console.log('Array!');
}
  • 1
    Ваш параграф и пример кода не совпадают. Кроме того, объекты могут иметь свойство .length .
  • 0
    Вы не можете проверить длину объекта. Можете ли вы дать мне пример свойства длины объекта
Показать ещё 2 комментария
0

Вот то, что я использую:

function isArray(input) {
  if (input instanceof Array || Object.prototype.toString.call(input) === '[object Array]') {
        return true;
  } else return false;
}
0

Вы можете найти с помощью push, как показано ниже:

function isArray(obj){
   return (typeof obj.push=== 'function')?true:false;
}

var array=new Array();
or
var array=['a','b','c'];
console.log(isArray(array));
0

Вы можете использовать эту функцию для получения типа данных.

var myAr  = [1,2];

checkType(myAr);

function checkType(data){
  if(typeof data ==='object'){
    if(Object.prototype.toString.call(data).indexOf('Array')!==(-1)){
      return 'array';
    } else{
      return 'object';
    }
  } else {
    return typeof data;
  }
}

if(checkType(myAr) === 'array'){console.log('yes, It is an array')};
  • 0
    Все, о чем просили, было простой эффективной проверкой.
0

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

function isArray (o) {
    return typeof o === "object" && o.length !== undefined;
}

isArray({}); // false
isArray(1); // false
isArray("str"); // false
isArray(function(){}); // false

isArray([]); // true

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

isArray({length:0}); // true

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

  • 0
    isArray (new String ()); возвращает истину
  • 0
    Да, я отметил это как ловушку в моих комментариях ниже примеров: «Единственная ловушка заключается в том, что она даст ложное срабатывание, если ваш объект имеет свойство длины»
0

Так как мне не нравятся вызовы Object.prototype, я искал другое решение. Тем более, что решения ChaosPandion не всегда будут работать, а решение MidnightTortoise с isArray() не работает с массивами, поступающими из DOM (например, getElementsByTagName). И, наконец, я нашел простое и кросс-браузерное решение, которое, вероятно, также могло бы работать с Netscape 4.;)

Это только эти 4 строки (проверка любого объекта h):

function isArray(h){
    if((h.length!=undefined&&h[0]!=undefined)||(h.length===0&&h[0]===undefined)){
        return true;
    }
    else{ return false; }
}

Я уже тестировал эти массивы (все возвращают true):

1) array=d.getElementsByName('some_element'); //'some_element' can be a real or unreal element
2) array=[];
3) array=[10];
4) array=new Array();
5) array=new Array();
   array.push("whatever");

Кто-нибудь может подтвердить, что это работает для всех случаев? Или кто-нибудь найдет случай, когда мое решение не работает?

  • 0
    Абсолютно. В качестве тривиального примера: jsfiddle.net/mnbayazit/fDwwV
  • 2
    Слишком много ложных срабатываний. isArray(function(){}); // true , isArray("foo"); // true , isArray({length:0}); // true
Показать ещё 5 комментариев
-4
 var length = 16;                               // Number
 var lastName = "Johnson";                      // String
 var cars = ["Saab", "Volvo", "BMW"];           // Array
 var x = {firstName:"John", lastName:"Doe"};

 Object.prototype.myCheck= function(){
 if (this.constructor === Array){
          alert('array');
        }else if (this.constructor === Object)
       {
         alert('object');
        }else if (this.constructor === Number)
        {
          alert('number');
        }else if (this.constructor === String)
        {
          alert('string');
        }

 }
 cars.myCheck();
 lastName.myCheck();
 length.myCheck();
  • 1
    Почему вы сделали свой метод прототипом Object, если не собираетесь называть его как cars.myCheck() ?
  • 0
    да отметьте что вы правы это должен быть cars.myCheck () .. обновил ответ
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню