Определить, является ли переданный параметр массивом? Javascript

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

У меня простой вопрос:

Как определить, является ли параметр, переданный моей функции javascript, массивом? Я не верю, что могу проверить:

if (typeof paramThatCouldBeArray == 'array') 

Так возможно ли это?

Как бы я это сделал?

Заранее спасибо.


person Alex    schedule 04.05.2010    source источник
comment
Хм ... это заставляет меня задуматься. Может быть, мой дизайн функций плох, если бы его можно было передать что-нибудь еще. Но я больше спрашивал об этом из-за console.log(). Это меня заинтриговало, потому что если вы передадите ему массив, он выполнит итерацию по всему массиву и распечатает его. Хотя если вы просто передадите ему одну строку, он просто записывает это. Как оно работает?   -  person Alex    schedule 04.05.2010
comment
Извините, для преемственности, удаленный комментарий: Какие еще типы могут быть у параметра?   -  person Casey Chu    schedule 04.05.2010
comment
@Alex: в каком браузере? Он мог полагаться на Array.toString.   -  person outis    schedule 04.05.2010
comment
Похоже, они используют множество проверок, зависящих от браузера - проверьте строку 1992 по адресу getfirebug.com/releases/lite/1.2/firebug-lite.js   -  person Casey Chu    schedule 04.05.2010
comment
@Alex: обратите внимание, что в Chrome console.log является встроенной функцией и, следовательно, имеет доступ к информации, недоступной для сценария JS.   -  person outis    schedule 04.05.2010
comment
... Firebug использует то, что вызывает представления (code.google.com/p/fbug/source/browse/branches/firebug1.6/, code.google.com/p/fbug/source/browse/branches/firebug1.6/) для преобразования объектов, каждый из которых имеет метод supportsObject, который в основном использует instanceof (например, code.google.com/p/fbug/source/browse/branches/firebug1.6/). Firebug Lite (code.google.com /p/fbug/source/browse/branches/firebug1.6/lite/) косвенно использует toString (вызывает obj + '').   -  person outis    schedule 04.05.2010


Ответы (6)


if (param instanceof Array)
    ...

Изменить. По состоянию на 2016 год существует готовый метод, который позволяет улавливать больше угловых случаев, _ 2_, используется следующим образом:

if (Array.isArray(param))
    ...
person Casey Chu    schedule 04.05.2010
comment
Подходит для большинства случаев, но не работает в кросс-кадровых средах, обратите внимание на это статья. - person Christian C. Salvadó; 04.05.2010
comment
!!param.shift будет быстрее с точки зрения скорости выполнения. jsperf.com/instanceof-vs-method-detect - person Bart; 27.05.2014
comment
Можно ли предположить, что это будет правильно работать под nodejs (поскольку я предполагаю, что есть только один фрейм)? - person 131; 19.09.2014
comment
Если вы точно знаете, что не будете работать с фреймами (как это обычно бывает), используйте метод конструктора. Сравнение производительности: jsperf.com/detecting-arrays-new - person thdoan; 30.01.2015
comment
По состоянию на 2016 год это все еще в целом эффективное и надежное решение. - person T.W.R. Cole; 07.06.2016

Это подход, который использует jQuery 1.4.2:

var toString = param.prototype.toString;
var isArray = function(obj) {
        return toString.call(obj) === "[object Array]";
    }
person James Westgate    schedule 04.05.2010
comment
Это toString сравнение может показаться странным, но это общепринятый способ работы с перекрестными кадрами. - person Halcyon; 23.11.2011
comment
Я не совсем понимаю: я определяю toString на основе param, а потом вызываю isArray()? Что я могу передать как obj? Где нижняя строка этого ответа? - person Tom; 21.08.2012
comment
Том, в основном каждый объект имеет функцию toString, которая «переопределяется» для массива и согласно спецификации возвращает [массив объектов]. Это единообразно для всех реализаций js. Прототип просто так, чтобы была указана одна функция. - person James Westgate; 22.08.2012
comment
Что, если param - это строка [массив объектов]? Я думаю, что вызов toString в строке возвращает саму строку - person ; 25.01.2017

Я нашел этот здесь:

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

также этот

function isArray(obj) {
    return (obj.constructor.toString().indexOf(”Array”) != -1);
}
person Germán Rodríguez    schedule 04.05.2010
comment
Тестирование с помощью JScript obj.constructor.toString() возвращает function Array() { [native code] }, заставляя это решение работать в этой среде. - person tresf; 25.10.2018

Вы можете протестировать свойство constructor:

if (param.constructor == Array) {
    ...
}

Хотя это будет включать объекты, у которых есть прототип массива,

function Stack() {
}
Stack.prototype = [];

если они также не определяют конструктор:

Stack.prototype.constructor = Stack;

or:

function Stack() {
    this.constructor = Stack;
}
person outis    schedule 04.05.2010

Несколько дней назад я создавал простую функцию определения типа, может быть, она полезна для тебя:

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

//...
if (typeString(obj) == 'array') {
  //..
}

Выполнение:

function typeString(o) {
  if (typeof o != 'object')
    return typeof o;

  if (o === null)
      return "null";
  //object, array, function, date, regexp, string, number, boolean, error
  var internalClass = Object.prototype.toString.call(o)
                                               .match(/\[object\s(\w+)\]/)[1];
  return internalClass.toLowerCase();
}

второй вариант этой функции более строгий, поскольку он возвращает только типы объектов, описанные в спецификация ECMAScript (возможные выходные значения: "object", "undefined", "null" и "function", "array", "date", "regexp", "string", "number", "boolean" "error", используя _ 14_ внутреннее свойство).

person Christian C. Salvadó    schedule 04.05.2010
comment
CMS, обе ваши ссылки на Gist мертвы. У тебя еще есть этот код? - person Jared Farrish; 05.02.2012

Утка Typying

На самом деле вам не обязательно проверять, является ли объект массивом. Вам следует набрать его, и единственное, что вы хотите, чтобы этот объект реализовал, - это свойство length. После этого вы можете преобразовать его в массив:

var arrayLike = {
    length : 3,

    0: "foo"
};

// transform object to array
var array = Array.prototype.slice.call(arrayLike);

JSON.stringify(array); // ["foo", null, null]

Array.prototype.slice.call(object) преобразует в массив каждый объект, который предоставляет свойство length. В случае строк, например:

var array = Array.prototype.slice.call("123");
JSON.stringify(array); // ["1", "2", "3"]

Что ж, этот метод не совсем работает в IE6 (я не знаю о более поздних версиях), но легко создать небольшую служебную функцию для преобразования объектов в массивах.

person Ionuț G. Stan    schedule 04.05.2010