Я пытаюсь написать функцию, которая принимает список строк или одну строку. Если это строка, то я хочу преобразовать ее в массив только с одним элементом, чтобы я мог зацикливаться на ней, не опасаясь ошибки.
Так как же проверить, является ли переменная массивом?
Я собрал различные решения ниже и создал тест jsperf . Все они быстрые, так что просто используйте Array.isArray
- теперь они хорошо поддерживаются и работают в разных кадрах .
arr.constructor === Array
самый быстрый.arr.constructor === Array
тест вернет false.Array.isArray(arr)
все еще возвращает истину, хотя.Ответы:
В современных браузерах вы можете сделать
( Поддерживается Chrome 5, Firefox 4.0, IE 9, Opera 10.5 и Safari 5)
Для обратной совместимости вы можете добавить следующее
Если вы используете JQuery, вы можете использовать
jQuery.isArray(obj)
или$.isArray(obj)
. Если вы используете подчеркивание, вы можете использовать_.isArray(obj)
Если вам не нужно обнаруживать массивы, созданные в разных кадрах, вы также можете просто использовать
instanceof
источник
Array.isArray
if (typeof Array.isArray === 'undefined') {
может быть изменено наif(!Array.isArray) {
Object.prototype.string.call(obj)
может быть подделан, если на нем есть объектSymbol.toStringTag
. Тем не менее, я не знаю ни о какой среде, которая отправляет,Symbol.toStringTag
но неArray.isArray
так, что это кажется безопасным.instanceof Array
сбой, если массив из другого фрейма?instanceof Array
сбой, если массив из другого фрейма, потому что каждый массив из этого фрейма имеет свойArray
конструктор и прототип. По соображениям совместимости / безопасности каждый кадр имеет свою собственную глобальную среду, включая глобальные объекты.Object
Глобальный от одного кадра отличается отObject
глобальной от другого. Так же и дляArray
глобалов. Аксель Раушмайер больше говорит об этом .Метод, указанный в стандарте ECMAScript для поиска класса Object, заключается в использовании
toString
метода изObject.prototype
.Или вы можете использовать
typeof
для проверки, если это строка:Или, если вы не беспокоитесь о производительности, вы можете просто создать
concat
новый пустой массив.Также есть конструктор, который вы можете запросить напрямую:
Заканчивать тщательное лечение от @TJ Crowder в блоге, как размещено в комментариях ниже.
Проверьте этот тест, чтобы понять, какой метод работает лучше: http://jsben.ch/#/QgYAV
Из @Bharath преобразуйте строку в массив, используя Es6 для поставленного вопроса:
предположим:
источник
toString
это один из способов пойти. Я делаю небольшую сводкуtypeof new String('beans')
> 'объект'Array.isArray(obj)
Я бы сначала проверил, поддерживает ли ваша реализация
isArray
:Вы также можете попробовать использовать
instanceof
оператористочник
v instanceof Array
вернет false, еслиv
был создан в другом фрейме (v
это экземплярthatFrame.contentWindow.Array
класса).Array.isArray
определяется как часть ECMAScript 5 / Javascript 1.8.5.return (Array.isArray && Array.isArray(v)) || (v instanceof Array);
JQuery также предлагает
$.isArray()
метод:источник
$.isArray === Array.isArray
возвращает истину.Array.isArray
за кулисами: github.com/jquery/jquery/blob/master/src/core.js#L211Это самый быстрый из всех методов (поддерживаются все браузеры):
источник
if (obj && Array === obj.constructor)
а неif (obj && obj.constructor === Array)
? Это потерянное в переводе на английский, а затем на код? Например, говорящие на английском языке обычно задают вопрос «существует ли объект и является ли он конструктором из класса массива?», поэтому поток кода при чтении более логичен. или есть какая-то техническая причина?function object_type(o){var t = typeof(o);return ((t==="object") && (o.constructor===Array)) ? "array" : t;} /*allows you to */ switch(object_type(o)){ case 'array': break; case 'object' : o.dosomething();}
Представьте, что у вас есть этот массив ниже :
Javascript (новые и старые браузеры):
или
или
тогда назовите это так:
Javascript (IE9 +, Ch5 +, FF4 +, Saf5 +, Opera10.5 +)
JQuery:
Угловой:
Подчеркни и Лодаш:
источник
Array.isArray работает быстро, но поддерживается не всеми версиями браузеров. Таким образом, вы можете сделать исключение для других и использовать универсальный метод:
источник
.toString()
метод отObject.prototype
. Прямо сейчас вы используете тоwindow.toString()
, что не то же самое.window.toString
сделать так же, какObject.prototype.toString
только в Chrome.Простая функция, чтобы проверить это:
источник
return object.constructor === Array
- но вы уверены, что это вернет true только для массивов?if(x) return true; else return false
сводит с ума, когда я вижу :-) Даже если это задом наперед, вы должны отрицать выражение.Как MDN говорит здесь :
Нравится:
Object.prototype.toString.call(arr) === '[object Array]'
, илиArray.isArray(arr)
источник
Есть только одно решение для этого вопроса
где x - переменная, она вернет true, если x - массив, и false, если это не так.
источник
typeof
сравнение.{}
массив, вы получите синтаксическую ошибку.Вы можете проверить тип вашей переменной, является ли она массивом с;
источник
instanceof
... Я думаю, что это терпит неудачу в нескольких странных сценариях.Я бы сделал функцию для проверки типа объекта, с которым вы имеете дело ...
тогда вы можете написать простое утверждение if ...
источник
Я делаю это очень простым способом. Работает для меня. Есть ли недостатки?
источник
{isArray:true}
JSON.parse(someDataFromElsewhere).items.isArray
может вернуть true (в зависимости от данных) и нарушить ваш код.Это моя попытка улучшить этот ответ с учетом комментариев:
Он избавляется от if / else и учитывает возможность того, что массив будет нулевым или неопределенным
источник
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray
источник
Я обновил скрипку jsperf двумя альтернативными методами, а также проверкой ошибок.
Оказывается, что метод, определяющий постоянное значение в прототипах «Объект» и «Массив», работает быстрее, чем любой другой метод. Это несколько удивительный результат.
Эти два метода не работают, если переменная принимает неопределенное значение, но они работают, если вы уверены, что они имеют значение. Что касается проверки с учетом производительности, является ли значение массивом или единственным значением, второй метод выглядит как допустимый быстрый метод. Это немного быстрее, чем instanceof в Chrome, в два раза быстрее, чем второй лучший метод в Internet Explorer, Opera и Safari (на моей машине).
источник
Я знаю, что люди ищут какой-то грубый подход к JavaScript. Но если вы хотите меньше думать, посмотрите здесь: http://underscorejs.org/#isArray
Возвращает true, если объект является массивом.
источник
Лучшее решение, которое я видел, это кросс-браузерная замена для typeof. Проверьте решение Ангуса Кролла здесь .
Ниже приведена версия TL; DR, но статья является отличным обсуждением этой проблемы, поэтому вам следует прочитать ее, если у вас есть время.
источник
Вот мой ленивый подход:
Я знаю, что кощунственно «связываться» с прототипом, но, похоже, он работает значительно лучше, чем рекомендуемый
toString
метод .Примечание: ловушка этого подхода заключается в том, что он не будет работать через
iframe
границы , но для моего варианта использования это не проблема.источник
wat = {array_: true}
объектами.obj.array_ = true
, то ты просто обманываешь себя .cache
объекте для запоминания результатов поиска, который использует строки поиска в качестве ключей свойств. Что делать, если пользователь ищетarray_
? Ваш объект становится массивом из-за этого? Это просто ошибка..array_
используется для маркировки массивов. Это действительно не тот случай,.array
может означать что угодно. Вы должны по крайней мере использовать описательную строку и сигнализировать о неприемлемости произвольного использования, например, с помощью.__isArray = true
.В книге Стояна Стефанова « Шаблоны JavaScript» есть хороший пример, который предполагает обработку всех возможных проблем, а также использует метод Array.isArray () ECMAScript 5 .
Итак, вот оно:
Кстати, если вы используете jQuery, вы можете использовать его метод $ .isArray ()
источник
if(!Array.isArray) {...
?Самый простой и быстрый способ проверить, является ли объект массивом или нет.
или
или вы можете сделать служебную функцию:
Применение:
источник
Следующее может быть использовано, если вы знаете, что у вашего объекта нет метода concat.
источник
Вы могли бы isArray метод, но я бы предпочел проверить с
Object.getPrototypeOf(yourvariable) === Array.prototype
источник
Object.getPrototypeOf(yourvariable)
возвращает прототип объекта Array. И код является самым быстрым и безопасным, чтобы на него можно было положиться.Если только два вида значений, которые могут быть переданы этой функции, являются строкой или массивом строк, сделайте это простым и используйте
typeof
проверку на возможность строки:источник
В поисках самой короткой версии вот что я получил до сих пор.
Обратите внимание, что не существует совершенной функции, которая всегда обнаруживает все возможные комбинации. Лучше знать все возможности и ограничения ваших инструментов, чем ожидать магического инструмента.
источник
A.map !== undefined
но да, это может быть скользкой дорогой в мире обезьяньих патчеров;)источник
Простая функция для проверки, является ли входное значение массивом, выглядит следующим образом:
Это работает кросс-браузер и со старыми браузерами. Это взято из сообщения в блоге TJ Crowders
источник
Вы можете попробовать это:
источник
Эта функция превратит почти все в массив:
Он использует некоторые новые функции браузера, поэтому вы можете захотеть заполнить его для максимальной поддержки.
Примеры:
NB строки будут преобразованы в массив с одним элементом вместо массива символов. Удалить
isString
чек, если вы предпочитаете его наоборот.Я использовал
Array.isArray
здесь, потому что это самый надежный и простой.источник
В вашем случае вы можете использовать
concat
метод Array, который может принимать как отдельные объекты, так и массивы (и даже комбинированные):concat
кажется, один из самых старых методов Array (даже IE 5.5 хорошо это знает).источник