Eu tenho um objeto JavaScript como o seguinte:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Agora eu quero percorrer todos p
os elementos ( p1
, p2
, p3
...) e obter as suas chaves e valores. Como eu posso fazer isso?
Eu posso modificar o objeto JavaScript, se necessário. Meu objetivo final é percorrer alguns pares de valores-chave e, se possível, quero evitar o uso eval
.
javascript
loops
for-loop
each
Tanmoy
fonte
fonte
Respostas:
Você pode usar o
for-in
loop como mostrado por outras pessoas. No entanto, você também precisa se certificar de que a chave que obtém é uma propriedade real de um objeto e não vem do protótipo.Aqui está o trecho:
For-of com Object.keys () alternativa:
Observe que o uso de, em
for-of
vez defor-in
, se não for usado, retornará indefinido nas propriedades nomeadas eObject.keys()
assegura o uso apenas das próprias propriedades do objeto sem as propriedades da cadeia de protótipos inteirasUsando o novo
Object.entries()
método:Nota: Este método não é suportado nativamente pelo Internet Explorer. Você pode considerar usar um Polyfill para navegadores mais antigos.
fonte
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
orprototype
. Esta propriedade tem uma referência ao seu objeto pai. Um objeto herda automaticamente a propriedade de seu pai. Essa é a razão do usohasOwnProperty
, o que significa que estamos interessados na propriedade dos objetos e não nos seus pais.No ECMAScript 5, você pode combinar
Object.keys()
eArray.prototype.forEach()
:O ECMAScript 6 acrescenta
for...of
:O ECMAScript 8 adiciona o
Object.entries()
que evita a necessidade de procurar cada valor no objeto original:Você pode combinar
for...of
, desestruturar eObject.entries
:As propriedades
Object.keys()
eObject.entries()
iteram na mesma ordem que umfor...in
loop, mas ignoram a cadeia de protótipos . Somente as propriedades enumeráveis do próprio objeto são iteradas.fonte
Object.forEach(obj, function (value, key) {...})
? :( Certamenteobj.forEach(function...)
seria mais curto e complementoArray.prototype.forEach
, mas que correria o risco de ter objetos definir a sua própriaforEach
propriedade suponho.Object.keys
Protege contra o callback modificar chaves do objeto.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([chave, valor] é variedade desestruturação, para acessar ambos os itens diretamente E você tem que envolver os parâmetros em parênteses adicionais..)index
a chave em json? Ou, se necessário, devo usar um contador separado?for...of
é o padrão ES6, não o ES2016.Você precisa usar o loop for-in
Mas tenha muito cuidado ao usar esse tipo de loop, porque isso fará um loop em todas as propriedades ao longo da cadeia de protótipos .
Portanto, ao usar loops de entrada, sempre use o
hasOwnProperty
método para determinar se a propriedade atual na iteração é realmente uma propriedade do objeto que você está verificando:fonte
{ }
pessoalmente porque umif
sem eles torna um pouco claro o que faz parteif
e o que não é. Mas eu acho que é apenas uma questão de opinião :){ }
principal para evitar confusão, se mais tarde precisar adicionar algo aoif
escopo.Object.prototype.hasOwnProperty.call(p, prop)
No entanto, isso também não pode proteger contra manipulações para Object.prototype ...A pergunta não estará completa se não mencionarmos métodos alternativos para percorrer objetos.
Atualmente, muitas bibliotecas JavaScript conhecidas fornecem seus próprios métodos para iterar sobre coleções, ou seja, sobre matrizes , objetos e objetos semelhantes a matrizes . Esses métodos são fáceis de usar e são totalmente compatíveis com qualquer navegador.
Se você trabalha com jQuery , pode usar o
jQuery.each()
método Ele pode ser usado para iterar perfeitamente objetos e matrizes:No Underscore.js, você encontra o método
_.each()
, que itera sobre uma lista de elementos, resultando cada um em uma função fornecida (preste atenção à ordem dos argumentos na função iteratee !):O Lo-Dash fornece vários métodos para iterar sobre as propriedades do objeto. Básico
_.forEach()
(ou seu alias_.each()
) é útil para fazer loop entre objetos e matrizes, no entanto (!) Objetos comlength
propriedade são tratados como matrizes, e para evitar esse comportamento, é recomendável usar métodos_.forIn()
e_.forOwn()
métodos (estes também têmvalue
argumentos em primeiro lugar):_.forIn()
itera sobre propriedades enumeráveis próprias e herdadas de um objeto, enquanto_.forOwn()
itera apenas sobre propriedades próprias de um objeto (basicamente verificando ahasOwnProperty
função). Para objetos simples e literais de objeto, qualquer um desses métodos funcionará bem.Geralmente todos os métodos descritos têm o mesmo comportamento com todos os objetos fornecidos. Além de usar o
for..in
loop nativo , geralmente será mais rápido do que qualquer abstração, como, por exemplojQuery.each()
, esses métodos são consideravelmente mais fáceis de usar, exigem menos codificação e fornecem melhor tratamento de erros.fonte
No ECMAScript 5, você tem uma nova abordagem nos campos de iteração literal -
Object.keys
Mais informações que você pode ver no MDN
Minha opção está abaixo como uma solução mais rápida nas versões atuais de navegadores (Chrome30, IE10, FF25)
Você pode comparar o desempenho dessa abordagem com diferentes implementações em jsperf.com :
Suporte ao navegador que você pode ver na tabela de compatibilidade do Kangax
Para o navegador antigo, você tem o polyfill simples e completo
UPD:
comparação de desempenho para todos os casos mais populares nesta pergunta em
perfjs.info
:iteração literal do objeto
fonte
Prefácio:
Aqui em 2018, suas opções para percorrer as propriedades de um objeto são (alguns exemplos seguem a lista):
for-in
[ MDN , spec ] - Uma estrutura de loop que percorre os nomes das propriedades enumeráveis de um objeto , incluindo as herdadas, cujos nomes são cadeiasObject.keys
[ MDN , especificação ] - A função de fornecer uma matriz dos nomes dos de um objeto próprio , enumeráveis propriedades cujos nomes são strings.Object.values
[ MDN , especificação ] - Uma função de proporcionar uma matriz de valores de de um objecto próprios , enumeráveis propriedades.Object.entries
[ MDN , especificação ] - Uma função que fornece uma disposição dos nomes e os valores de de um objecto próprios , enumeráveis propriedades (cada entrada na matriz é uma[name, value]
matriz).Object.getOwnPropertyNames
[ MDN , especificação ] - A função de fornecer uma matriz dos nomes dos de um objeto próprias propriedades (mesmo os não-enumeráveis) cujos nomes são strings.Object.getOwnPropertySymbols
[ MDN , especificação ] - A função de fornecer uma matriz dos nomes dos de um objeto próprias propriedades (mesmo os não-enumeráveis) cujos nomes são símbolos.Reflect.ownKeys
[ MDN , especificação ] - Uma função que fornece uma disposição dos nomes dos de um objecto próprias propriedades (mesmo aqueles não-enumeráveis), se esses nomes são cadeias de caracteres ou símbolos.Object.getPrototypeOf
[ MDN , especificação ] e utilizaçãoObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
ouReflect.ownKeys
em cada objeto na cadeia de protótipos (exemplo na parte inferior desta resposta).Com todos eles, exceto
for-in
, você pode usar algum tipo de looping construção no array (for
,for-of
,forEach
, etc.).Exemplos:
for-in
:Mostrar snippet de código
Object.keys
(com umfor-of
loop, mas você pode usar qualquer construção de loop) :Mostrar snippet de código
Object.values
:Mostrar snippet de código
Object.entries
:Mostrar snippet de código
Object.getOwnPropertyNames
:Mostrar snippet de código
Object.getOwnPropertySymbols
:Mostrar snippet de código
Reflect.ownKeys
:Mostrar snippet de código
Todas as propriedades , incluindo as não enumeráveis herdadas:
Mostrar snippet de código
fonte
Você pode simplesmente iterar sobre isso como:
Observe que
key
não assumirá o valor da propriedade, é apenas um valor de índice.fonte
Como o es2015 está se tornando cada vez mais popular, estou postando esta resposta, que inclui o uso de gerador e iterador para iterar suavemente através de
[key, value]
pares. Como é possível em outros idiomas, por exemplo, Ruby.Ok, aqui está um código:
Todas as informações sobre como você pode criar um iterador e gerador podem ser encontradas na página do desenvolvedor Mozilla.
Espero que tenha ajudado alguém.
EDITAR:
O ES2017 incluirá o
Object.entries
que tornará a iteração sobre[key, value]
pares em objetos ainda mais fácil. Sabe-se agora que fará parte de um padrão de acordo com as informações do estágio ts39 .Acho que está na hora de atualizar minha resposta para deixá-la ainda mais atual do que é agora.
Você pode encontrar mais informações sobre o uso na página MDN
fonte
Nota: você pode fazer isso através de matrizes, mas também repetirá as
length
propriedades e outras.fonte
key
apenas assumirá um valor de índice, de modo que apenas alertará 0, 1, 2, etc ... Você precisa acessar p [tecla].var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
está aparecendo "p1" e "p2" em alertas, então o que há de errado nisso ???Depois de examinar todas as respostas aqui, o hasOwnProperty não é necessário para meu próprio uso porque meu objeto json está limpo; realmente não faz sentido adicionar nenhum processamento javascript adicional. Isso é tudo o que estou usando:
fonte
Object.prototype
, ele será enumerado porfor..in
. Se você tiver certeza de que não está usando nenhuma biblioteca que faça isso, não precisará ligarhasOwnProperty
.Object.create(null)
através da protótipo com forEach (), que deve pular as propriedades da cadeia de protótipos :
fonte
obj = { print: 1, each: 2, word: 3 }
produzTypeError: number is not a function
. UsarforEach
para combinar com aArray
função semelhante pode reduzir um pouco o risco.É pessoas interessantes nestas respostas tocaram em ambos
Object.keys()
efor...of
mas nunca combinou-os:Você pode não apenas
for...of
umObject
, porque não é um iterador, efor...index
ou.forEach()
ing oObject.keys()
é feio / ineficiente.Fico feliz que a maioria das pessoas se abstenha de
for...in
(com ou sem verificação.hasOwnProperty()
), pois isso também é um pouco confuso, então, além da minha resposta acima, estou aqui para dizer ...Você pode fazer associações de objetos comuns iterarem! Comportando-se como
Map
s com o uso direto dafor...of
DEMO chique trabalhando no Chrome e no FF (presumo apenas o ES6)
Contanto que você inclua meu calço abaixo:
Sem ter que criar um objeto de mapa real que não tenha o bom açúcar sintático.
De fato, com esse calço, se você ainda deseja tirar proveito das outras funcionalidades do Map (sem compor todas), mas ainda deseja usar a notação de objeto, uma vez que os objetos agora são iteráveis, agora você pode fazer um mapa a partir dele!
Para quem não gosta de brincar ou mexer
prototype
em geral, sinta-se à vontade para fazer a função na janela, chamando-a de algo parecido comgetObjIterator()
isso;Agora você pode chamá-lo como uma função comum, nada mais é afetado
ou
Não há razão para que isso não funcione.
Bem vindo ao futuro.
fonte
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
para enfatizar que a magia ainda funciona para esses tipos). Você checou as demos; o que não está funcionando para você, @ noɥʇʎԀʎzɐɹƆ? (PS sua imagem de perfil SE é chefe)Portanto, ele fornece a mesma lista de chaves que você pretende, testando cada chave de objeto com hasOwnProperty. Você não precisa dessa operação de teste extra e
Object.keys( obj ).forEach(function( key ){})
deve ser mais rápida. Vamos provar:No meu Firefox, tenho os seguintes resultados
PS. no Chrome, a diferença ainda maior http://codepen.io/dsheiko/pen/JdrqXa
PS2: no ES6 (EcmaScript 2015), você pode iterar objetos iteráveis melhor:
fonte
of
sem criarMap
sAqui está outro método para iterar através de um objeto.
fonte
for
método pode ser mais eficiente.fonte
Você também pode usar Object.keys () e iterar sobre as chaves de objeto, como abaixo, para obter o valor:
fonte
Somente código JavaScript sem dependências:
fonte
O
Object.keys()
método retorna uma matriz das propriedades enumeráveis de um determinado objeto. Leia mais sobre isso aquifonte
atuação
Hoje 2020.03.06 realizo testes de soluções escolhidas no Chrome v80.0, Safari v13.0.5 e Firefox 73.0.1 no MacOs High Sierra v10.13.6
Conclusões
for-in
(A, B) são rápidas (ou mais rápidas) para todos os navegadores para objetos grandes e pequenosfor-of
(H) a solução é rápida no chrome para objetos pequenos e grandesi
(J, K) são bastante rápidas em todos os navegadores para objetos pequenos (para o firefox também são rápidas em objetos grandes, mas são rápidas em outros navegadores)Detalhes
Testes de desempenho foram realizados para
Os trechos abaixo apresentam soluções usadas
Mostrar snippet de código
E aqui estão os resultados para pequenos objetos no chrome
fonte
Você pode adicionar uma função forEach simples a todos os objetos, para poder percorrer automaticamente qualquer objeto:
Para aquelas pessoas que não gostam do método " for ... in ":
Agora, você pode simplesmente ligar para:
Se você não deseja entrar em conflito com outros métodos forEach, você pode nomear com seu nome exclusivo.
fonte
Object
internos (como ) geralmente é considerado um antipadrão, pois pode facilmente causar conflitos com outro código. Portanto, não recomendo fazer dessa maneira.Os loops podem ser bastante interessantes ao usar JavaScript puro. Parece que apenas o ECMA6 (nova especificação JavaScript de 2015) controlou os loops. Infelizmente, enquanto escrevo isso, os navegadores e o popular ambiente de desenvolvimento integrado (IDE) ainda estão lutando para oferecer suporte completo aos novos sinos e assobios.
À primeira vista, aqui está a aparência de um loop de objeto JavaScript antes do ECMA6:
Além disso, eu sei que isso está fora de escopo com esta pergunta, mas em 2011, o ECMAScript 5.1 adicionou o
forEach
método para Arrays, o que basicamente criou uma nova maneira aprimorada de fazer um loop através de matrizes enquanto ainda deixa objetos não iteráveis com o antigofor
loop detalhado e confuso . Mas a parte estranha é que esse novoforEach
método não suporta obreak
que levou a todos os tipos de outros problemas.Basicamente, em 2011, não existe uma maneira realmente sólida de fazer loop no JavaScript, além do que muitas bibliotecas populares (jQuery, Underscore etc.) decidiram reimplementar.
A partir de 2015, agora temos uma maneira melhor e imediata de fazer loop (e quebrar) qualquer tipo de objeto (incluindo matrizes e seqüências de caracteres). Aqui está como será um loop em JavaScript quando a recomendação se tornar mainstream:
Observe que a maioria dos navegadores não suporta o código acima a partir de 18 de junho de 2016. Mesmo no Chrome, você precisa habilitar este sinalizador especial para que ele funcione:
chrome://flags/#enable-javascript-harmony
Até que este se torne o novo padrão, o método antigo ainda pode ser usado, mas também existem alternativas em bibliotecas populares ou até alternativas leves para aqueles que não estão usando nenhuma dessas bibliotecas.
fonte
Uncaught TypeError: Object.entries is not a function
. Ainda não está implementado no chrome?No ES6, temos símbolos conhecidos para expor alguns métodos internos anteriormente. Você pode usá-lo para definir como os iteradores funcionam para este objeto:
isso dará o mesmo resultado que usar for ... no loop es6.
Mas é importante conhecer os recursos que você tem agora usando o es6!
fonte
Object.keys()
e alocada na memória ... Legal!Eu faria isso ao invés de verificar
obj.hasOwnerProperty
dentro de cadafor ... in
loop.fonte
fonte
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Usando um
for-of
onObject.keys()
Gostar:
fonte
Se você quiser iterar também sobre propriedades não enumeráveis , poderá usar
Object.getOwnPropertyNames(obj)
para retornar uma matriz de todas as propriedades (enumeráveis ou não) encontradas diretamente em um determinado objeto.fonte
Error
objeto e não conseguia_.forIn(err)
acessar as propriedades em um loop ou em uma chamada. UsarObject.getOwnPropertyNames(err)
me permitiu acessar todas as partes doError
que eu não conseguia obter antes. Obrigado!Se alguém precisar fazer um loop através de arrayObjects com a condição :
fonte
Considerando o ES6, gostaria de adicionar minha própria colher de açúcar e fornecer mais uma abordagem para iterar as propriedades do objeto.
Como o objeto JS comum não é iterável apenas fora da caixa, não podemos usar o
for..of
loop para iterar sobre seu conteúdo. Mas ninguém pode nos parar para torná-lo iterável .Vamos ter
book
objeto.Desde que fizemos, podemos usá-lo desta maneira:
Ou, se você conhece o poder dos geradores ES6 , certamente pode tornar o código acima muito mais curto.
Claro, você pode aplicar esse comportamento a todos os objetos, tornando
Object
iterável noprototype
nível.Além disso, objetos que cumprem o protocolo iterável podem ser usados com o novo operador de dispersão de recursos do ES2015 , para que possamos ler os valores das propriedades dos objetos como uma matriz.
Ou você pode usar a atribuição de desestruturação :
Você pode conferir o JSFiddle com todo o código que forneci acima.
fonte
desde ES06, você pode obter os valores de um objeto como matriz com
retorna a matriz dos valores do objeto e não extrai valores do Prototype !!
DOCS MDN Object.values ()
e para chaves (já respondidas antes de mim aqui)
fonte
No script mais recente do ES, você pode fazer algo assim:
fonte