Как проверить, является ли переменная массивом в JavaScript? [дубликат]
этот вопрос уже есть ответ здесь:
Проверьте, является ли объект массивом?
40 ответов
Я хотел бы проверить, является ли переменная массивом или одним значением в JavaScript.
Я нашел возможное решение...
if (variable.constructor == Array)...
Это лучший способ это сделать?
23 ответов:
есть несколько способов проверить, является ли переменная массивом или нет. Лучшее решение - это то, которое вы выбрали.
variable.constructor === Arrayэто самый быстрый метод на Chrome, и, скорее всего, все другие браузеры. Все массивы являются объектами, поэтому проверка свойства конструктора является быстрым процессом для движков JavaScript.
если у вас возникли проблемы с выяснением, является ли свойство objects массивом, вы должны сначала проверить, является ли это свойство там.
variable.prop && variable.prop.constructor === Arrayнекоторыми другими способами являются:
variable instanceof Arrayэтот метод работает о
1/3 скоростикак первый пример. Все еще довольно твердый, выглядит чище, если вы все о красивом коде и не так много на производительности. Обратите внимание, что проверка чисел не работает какvariable instanceof Numberвсегда возвращаетfalse. обновление:instanceofтеперь идет 2/3 скорость!Array.isArray(variable)этот последний, на мой взгляд, самый уродливый, и он является одним из самый медленный. Запуск около 1/5 скорости в качестве первого примера. Матрица.прототип, на самом деле массив. вы можете прочитать больше об этом здесь 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 возвращается в интернет.
вы также можете использовать:
if (value instanceof Array) { alert('value is Array!'); } else { alert('Not an array'); }Это кажется мне довольно элегантным решением, но каждому свое.
Edit:
по состоянию на ES5 теперь также есть:
Array.isArray(value);но это сломается на старых браузерах, если вы не используете полифилл (в основном... IE8 или похожие).
Я заметил, что кто-то упомянул jQuery, но я не знал, что есть
isArray()
есть несколько решений со всеми своими причудами. на этой странице дает хороший обзор. Одним из возможных решений является:
function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]'; }
в современных браузерах (и некоторых устаревших браузерах), вы можете сделать
Array.isArray(obj)(при поддержке Chrome 5, Firefox 4.0, IE 9, Opera 10.5 и Safari 5)
Если вам нужно поддерживать более старые версии IE, вы можете использовать es5-shim к массиву polyfill.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)Если вам не надо обнаружение массивов, созданных в разных кадрах вы также можете просто использовать
instanceofobj instanceof Array
Примечание: the
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)
Это старый вопрос, но с той же проблемой я нашел очень элегантное решение, которым я хочу поделиться.
добавление прототипа в массив делает его очень простым
Array.prototype.isArray = true;теперь если у вас есть объект, который вы хотите проверить, чтобы увидеть, если массив все, что вам нужно, чтобы проверить новое свойство
var box = doSomething(); if (box.isArray) { // do something }isArray доступен только если его массив
через Крокфорд:
function typeOf(value) { var s = typeof value; if (s === 'object') { if (value) { if (value instanceof Array) { s = 'array'; } } else { s = 'null'; } } return s; }основной недостаток Крокфорд упоминает неспособность правильно определить массивы, которые были созданы в другом контексте, например,
window. Эта страница имеет гораздо более сложную версию, если этого недостаточно.
мне лично нравится предложение Питера: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 окончательное руководство 6-го издания, 7.10, он говорит
Array.isArray()реализуется с помощьюObject.prototype.toString.call()в ECMAScript 5. Также обратите внимание, что если вы собираетесь беспокоиться оtoString()реализация меняется, вы также должны беспокоиться о каждом другом встроенном методе изменения тоже. Зачем использоватьpush()? Кто-то может это изменить! Такой подход глупый. Выше проверка является предлагаемым решением для тех, кто беспокоится оtoString()меняется, но я считаю, что проверка не нужна.
подумал, что я бы добавил еще один вариант для тех, кто уже может использовать подчеркивание.библиотека js в их скрипте. Подчеркивать.js имеет функцию isArray () (см. http://underscorejs.org/#isArray).
_.isArray(object)возвращает true, если объект является массивом.
Если вы имеете дело только с EcmaScript 5 и выше, то вы можете использовать встроенный
Array.isArrayфункциинапример,
Array.isArray([]) // true Array.isArray("foo") // false Array.isArray({}) // false
Если вы используете угловой, вы можете использовать угловой.функция isArray ()
var myArray = []; angular.isArray(myArray); // returns true var myObj = {}; angular.isArray(myObj); //returns false
в Крокфорд это JavaScript Хорошие Части, есть функция для проверки, является ли данный аргумент массивом:
var is_array = function (value) { return value && typeof value === 'object' && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length')); };Он объясняет:
во-первых, мы спрашиваем, является ли значение истинным. Мы делаем это, чтобы отклонить null и другие ложные значения. Во-вторых, мы спрашиваем, является ли значение typeof "объектом". Это будет верно для объектов, массивов и (странно) null. В-третьих, мы спрашиваем, имеет ли значение свойство length, которое является числом. Это всегда будет верно для массивов, но обычно не для объектов. В-четвертых, мы спрашиваем, содержит ли значение метод сращивания. Это снова будет верно для всех массивов. Наконец, мы спрашиваем, является ли свойство length перечислимым (будет ли длина создаваться циклом for in?). Это будет ложь для всех массивов. Это самый надежный тест на массивность, который я нашел. К сожалению, это так сложно.
я использовал эту строку кода:
if (variable.push) { // variable is array, since AMAIK only arrays have push() method. }
универсальное решение ниже:
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
код, указанный из 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);};
для тех, кто кода-гольф, ненадежный тест с наименьшим количеством символов:
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]
С w3schools:
function isArray(myArray) { return myArray.constructor.toString().indexOf("Array") > -1; }
мне понравился ответ Брайана:
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([]);
Я создал этот маленький кусочек кода, который может возвращать true типов.
Я еще не уверен в производительности, но это попытка правильно определить тип.
https://github.com/valtido/better-typeOf также написал немного об этом здесь http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof/
он работает, как и текущий typeof.
var user = [1,2,3] typeOf(user); //[object Array]Я думаю, что это может понадобиться немного тонкой настройки, и принять во внимание вещи, я не сталкивался или проверить его должным образом. так что дальнейшие улучшения приветствуются, будь то с точки зрения производительности или неправильной отчетности оператора typeof.
Я думаю, используя myObj.конструктор= = объект и myArray.конструктор==массив-это лучший способ. Почти в 20 раз быстрее, чем с помощью функции toString(). Если вы расширяете объекты своими собственными конструкторами и хотите, чтобы эти творения считались "объектами", а также это не работает, но в противном случае его путь быстрее. typeof работает так же быстро, как и метод конструктора, но typeof []=='object' возвращает true, что часто нежелательно. http://jsperf.com/constructor-vs-tostring
одна вещь, чтобы отметить, что значение null.конструктор выдаст ошибку, поэтому, если вы можете проверять нулевые значения, вам придется сначала сделать if(testThing!= = null) {}
С тех пор .свойство length для массива в JavaScript, вы можете просто сказать
obj.length === +obj.length // true if obj is an arrayUnderscorejs и несколько других библиотек используют этот короткий и простой трюк.
Comments