Estou tentando escrever uma função que aceita uma lista de seqüências de caracteres ou uma única seqüência de caracteres. Se for uma string, quero convertê-la em uma matriz com apenas um item, para que eu possa fazer um loop sobre ela sem medo de erro.
Então, como verifico se a variável é uma matriz?
Reuni as várias soluções abaixo e criei um teste jsperf . Eles são todos rápidos, portanto, basta usar Array.isArray
- ele é bem suportado agora e funciona em vários quadros .
arr.constructor === Array
é o mais rápido.arr.constructor === Array
teste retornará falso.Array.isArray(arr)
ainda retorna verdadeiro embora.Respostas:
Nos navegadores modernos, você pode fazer
( Suportado pelo Chrome 5, Firefox 4.0, IE 9, Opera 10.5 e Safari 5)
Para compatibilidade com versões anteriores, você pode adicionar o seguinte
Se você usa jQuery, pode usar
jQuery.isArray(obj)
ou$.isArray(obj)
. Se você usar sublinhado, poderá usar_.isArray(obj)
Se você não precisa detectar matrizes criadas em quadros diferentes, também pode usar
instanceof
fonte
Array.isArray
if (typeof Array.isArray === 'undefined') {
pode ser alterado paraif(!Array.isArray) {
Object.prototype.string.call(obj)
pode ser falsificado se o objetoSymbol.toStringTag
estiver nele. Dito isto, não conheço nenhum ambiente que seja enviado,Symbol.toStringTag
mas não,Array.isArray
portanto isso parece seguro.instanceof Array
falha se a matriz é de um quadro diferente?instanceof Array
falha se a matriz for de um quadro diferente porque cada matriz desse quadro diferente possui umArray
construtor e um protótipo diferentes . Por motivos de compatibilidade / segurança, todos os quadros têm seu próprio ambiente global e isso inclui objetos globais. OObject
global de um quadro é diferente doObject
global de outro. O mesmoArray
vale para os globais. Axel Rauschmayer fala mais sobre isso .O método fornecido no padrão ECMAScript para encontrar a classe de Object é usar o
toString
método deObject.prototype
.Ou você pode usar
typeof
para testar se é uma String:Ou, se você não está preocupado com o desempenho, basta fazer um
concat
para uma nova matriz vazia.Há também o construtor que você pode consultar diretamente:
Confira um tratamento completo no blog de @TJ Crowder , conforme publicado em seu comentário abaixo.
Confira este benchmark para ter uma idéia de qual método tem melhor desempenho: http://jsben.ch/#/QgYAV
De @Bharath, converta string em array usando Es6 para a pergunta:
suponha:
fonte
toString
é um dos caminhos a seguir. Eu faço um pouco de um resumo aqui: blog.niftysnippets.org/2010/09/say-what.htmltypeof new String('beans')
> 'objeto'Array.isArray(obj)
Primeiro, verificaria se sua implementação suporta
isArray
:Você também pode tentar usar o
instanceof
operadorfonte
v instanceof Array
retornará false sev
foi criado em outro quadro (v
é instância dathatFrame.contentWindow.Array
classe).Array.isArray
é definido como parte do ECMAScript 5 / Javascript 1.8.5.return (Array.isArray && Array.isArray(v)) || (v instanceof Array);
O jQuery também oferece um
$.isArray()
método:fonte
$.isArray === Array.isArray
está retornando verdadeiro.Array.isArray
nos bastidores: github.com/jquery/jquery/blob/master/src/core.js#L211Este é o mais rápido entre todos os métodos (todos os navegadores suportados):
fonte
if (obj && Array === obj.constructor)
em vez deif (obj && obj.constructor === Array)
? Está perdido na tradução para o inglês e depois no código? por exemplo, os falantes de inglês geralmente tendem a perguntar "o objeto existe e seu construtor vem da classe da matriz?", portanto o código flui ao lê-lo é mais lógico. ou existe algum motivo técnico?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();}
Imagine que você tem esta matriz abaixo :
Javascript (navegadores novos e antigos):
ou
ou
então chame assim:
Javascript (IE9 +, Ch5 +, FF4 +, Saf5 +, Opera10.5 +)
jQuery:
Angular:
Sublinhado e Lodash:
fonte
Array.isArray funciona rápido, mas não é suportado por todas as versões dos navegadores. Então você pode fazer uma exceção para outras pessoas e usar o método universal:
fonte
.toString()
métodoObject.prototype
. No momento, você está usando owindow.toString()
, que não é o mesmo.window.toString
faça o mesmo queObject.prototype.toString
apenas no Chrome.Função simples para verificar isso:
fonte
return object.constructor === Array
- mas você tem certeza de que isso só retornará verdadeiro para matrizes?if(x) return true; else return false
:-) Mesmo que seja ao contrário, você deve negar a expressão.Como a MDN diz aqui :
Como isso:
Object.prototype.toString.call(arr) === '[object Array]'
ouArray.isArray(arr)
fonte
Existe apenas uma solução de linha para esta pergunta
onde x é a variável, retornará true se x for uma matriz e false se não for.
fonte
typeof
comparação.{}
uma matriz, você recebe um erro de sintaxe.Você pode verificar o tipo de sua variável se é uma matriz com;
fonte
instanceof
.. Acho que falha em alguns cenários estranhos.Eu faria uma função para testar o tipo de objeto com o qual você está lidando ...
então você pode escrever uma declaração if simples ...
fonte
Eu faço isso de uma maneira muito simples. Funciona para mim. Alguma desvantagem?
fonte
{isArray:true}
JSON.parse(someDataFromElsewhere).items.isArray
pode retornar true (dependendo dos dados) e quebrar seu código.Esta é minha tentativa de melhorar esta resposta, levando em consideração os comentários:
Ele se livra do if / else e explica a possibilidade de o array ser nulo ou indefinido
fonte
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray
fonte
Atualizei o jsperf fiddle com dois métodos alternativos, bem como com a verificação de erros.
Acontece que o método que define um valor constante nos protótipos 'Objeto' e 'Matriz' é mais rápido que qualquer outro método. É um resultado um tanto surpreendente.
Esses dois métodos não funcionam se a variável receber o valor indefinido, mas funcionarão se você tiver certeza de que eles têm um valor. Com relação à verificação com o desempenho em mente se um valor é uma matriz ou um valor único, o segundo método se parece com um método rápido válido. É um pouco mais rápido que 'instanceof' no Chrome, duas vezes mais rápido que o segundo melhor método no Internet Explorer, Opera e Safari (na minha máquina).
fonte
Eu sei que as pessoas estão procurando algum tipo de abordagem javascript bruta. Mas se você quiser pensar menos, dê uma olhada aqui: http://underscorejs.org/#isArray
Retorna true se o objeto for uma matriz.
fonte
A melhor solução que eu vi é uma substituição entre navegadores do typeof. Confira a solução da Angus Croll aqui .
A versão TL; DR está abaixo, mas o artigo é uma ótima discussão sobre o problema; portanto, você deve lê-lo se tiver tempo.
fonte
Aqui está minha abordagem preguiçosa:
Sei que é um sacrilégio "mexer com" o protótipo, mas ele parece ter um desempenho significativamente melhor que o
toString
método recomendado .Nota: Uma armadilha dessa abordagem é que ela não funcionará além dos
iframe
limites , mas para o meu caso de uso isso não é um problema.fonte
wat = {array_: true}
objetos.obj.array_ = true
, estará apenas se enganando .cache
objeto para memorizar os resultados da pesquisa que usa as cadeias de pesquisa como chaves de propriedade. E se um usuário pesquisararray_
? Seu objeto se torna uma matriz por causa disso? É apenas um bug..array_
é usado para marcar matrizes. Isso realmente não é o caso aqui,.array
pode significar qualquer coisa. Você deve pelo menos usar uma sequência descritiva e sinalizar inadequação de uso arbitrário, por exemplo, com.__isArray = true
.Há um bom exemplo no livro JavaScript Patterns, de Stoyan Stefanov, que supõe lidar com todos os problemas possíveis, além de utilizar o método Array.isArray () do ECMAScript 5 .
Então aqui está:
A propósito, se você estiver usando jQuery, poderá usar o método $ .isArray ()
fonte
if(!Array.isArray) {...
?A maneira mais fácil e rápida de verificar se um Objeto é uma Matriz ou não.
ou
ou você pode fazer uma função de utilitário:
uso:
fonte
O seguinte pode ser usado se você souber que seu objeto não possui um método concat.
fonte
Você poderia é o método isArray, mas eu preferiria verificar com
Object.getPrototypeOf(yourvariable) === Array.prototype
fonte
Object.getPrototypeOf(yourvariable)
retorna o protótipo de um objeto Array. E o código é mais rápido e seguro.Se os únicos dois tipos de valores que podem ser passados para essa função são uma sequência ou uma matriz de sequências, mantenha-a simples e use uma
typeof
verificação da possibilidade de sequência:fonte
Em busca da versão mais curta, aqui está o que eu consegui até agora.
Observe que não existe uma função perfeita que sempre detecte todas as combinações possíveis. É melhor conhecer todas as habilidades e limitações de suas ferramentas do que esperar uma ferramenta mágica.
fonte
A.map !== undefined
, mas sim, que poderia ser estrada escorregadio no mundo do macaco patchers;)fonte
Uma função simples para testar se um valor de entrada é uma matriz é o seguinte:
Isso funciona em vários navegadores e com navegadores mais antigos. Isso é retirado da postagem do blog de TJ Crowders
fonte
Você pode tentar isso:
fonte
Esta função transformará quase tudo em uma matriz:
Ele usa alguns recursos mais recentes do navegador, portanto, você pode preencher isso para obter o máximo suporte.
Exemplos:
NB seqüências serão convertidas em uma matriz com um único elemento em vez de uma matriz de caracteres. Exclua a
isString
verificação se você preferir o contrário.Eu usei
Array.isArray
aqui porque é o mais robusto e também o mais simples.fonte
No seu caso, você pode usar o
concat
método Array, que pode aceitar objetos únicos e também array (e até combinado):concat
parece ser um dos métodos mais antigos do Array (até o IE 5.5 o conhece bem).fonte