Se houver um objeto Javascript:
var objects={...};
Suponha que ele tenha mais de 50 propriedades, sem saber os nomes das propriedades (sem saber as 'chaves') como obter cada valor de propriedade em um loop?
Se houver um objeto Javascript:
var objects={...};
Suponha que ele tenha mais de 50 propriedades, sem saber os nomes das propriedades (sem saber as 'chaves') como obter cada valor de propriedade em um loop?
Respostas:
Usando um for..in
loop simples :
for(var key in objects) {
var value = objects[key];
}
enumerable
sinalizador definido como falso. Isso - entre outras coisas - significa que você não repetirá nenhum método de classe, mas que repetirá métodos criados de outras maneiras.
Dependendo de quais navegadores você precisa oferecer suporte, isso pode ser feito de várias maneiras. A esmagadora maioria dos navegadores em estado selvagem oferece suporte ao ECMAScript 5 (ES5), mas esteja avisado de que muitos dos exemplos abaixo usam Object.keys
, o que não está disponível no IE <9. Consulte a tabela de compatibilidade .
Se você precisar oferecer suporte a versões mais antigas do IE, esta é a opção para você:
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
O aninhado if
garante que você não enumere as propriedades na cadeia de protótipos do objeto (que é o comportamento que você quase certamente deseja). Você deve usar
Object.prototype.hasOwnProperty.call(obj, key) // ok
ao invés de
obj.hasOwnProperty(key) // bad
porque o ECMAScript 5+ permite criar objetos sem protótipo Object.create(null)
e esses objetos não terão o hasOwnProperty
método O código malicioso também pode produzir objetos que substituem o hasOwnProperty
método.
Você pode usar esses métodos em qualquer navegador que suporte o ECMAScript 5 e superior. Eles obtêm valores de um objeto e evitam enumerar a cadeia de protótipos. Onde obj
está o seu objeto:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
Se você quer algo um pouco mais compacto ou deseja ter cuidado com funções em loops, então Array.prototype.forEach
é seu amigo:
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
O próximo método cria uma matriz que contém os valores de um objeto. Isso é conveniente para fazer o loop.
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
Se você deseja tornar os usuários Object.keys
seguros contra null
(como for-in
estão), pode fazê-lo Object.keys(obj || {})...
.
Object.keys
retorna propriedades enumeráveis . Para iterar sobre objetos simples, isso geralmente é suficiente. Se você tiver algo com propriedades não enumeráveis com as quais precisa trabalhar, poderá usar Object.getOwnPropertyNames
no lugar de Object.keys
.
As matrizes são mais fáceis de iterar com o ECMAScript 2015. Você pode usar isso para sua vantagem ao trabalhar com valores um por um em um loop:
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
Usando as funções de seta de gordura do ECMAScript 2015, o mapeamento do objeto para uma matriz de valores se torna uma linha:
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
O ECMAScript 2015 apresenta Symbol
, instâncias das quais podem ser usadas como nomes de propriedades. Para obter os símbolos de um objeto para enumerar, use Object.getOwnPropertySymbols
(essa função é a razão pela qual Symbol
não pode ser usada para criar propriedades particulares). A nova Reflect
API do ECMAScript 2015 fornece Reflect.ownKeys
, que retorna uma lista de nomes de propriedades (incluindo nomes não enumeráveis) e símbolos.
As compreensões da matriz foram removidas do ECMAScript 6 antes da publicação. Antes da remoção, uma solução seria semelhante a:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
O ECMAScript 2016 adiciona recursos que não afetam esse assunto. A especificação ECMAScript 2017 adiciona Object.values
e Object.entries
. Ambas as matrizes de retorno (o que será surpreendente para alguns, dada a analogia com Array.entries
). Object.values
pode ser usado como está ou com um for-of
loop.
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
Se você deseja usar tanto a chave quanto o valor, então Object.entries
é para você. Produz uma matriz cheia de [key, value]
pares. Você pode usar isso como está, ou (observe também a atribuição de desestruturação do ECMAScript 2015) em um for-of
loop:
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values
calçoFinalmente, como observado nos comentários e por teh_senaus em outra resposta, pode valer a pena usar um deles como calço. Não se preocupe, o seguinte não altera o protótipo, apenas adiciona um método a Object
(que é muito menos perigoso). Usando funções de seta gorda, isso também pode ser feito em uma linha:
Object.values = obj => Object.keys(obj).map(key => obj[key]);
que agora você pode usar como
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
Se você deseja evitar o desgaste quando um nativo Object.values
existe, você pode:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Esteja ciente dos navegadores / versões que você precisa oferecer suporte. Os itens acima estão corretos onde os métodos ou recursos de linguagem são implementados. Por exemplo, o suporte ao ECMAScript 2015 foi desativado por padrão na V8 até recentemente, que alimentava navegadores como o Chrome. Os recursos do ECMAScript 2015 devem ser evitados até que os navegadores que você pretende oferecer suporte implementem os recursos necessários. Se você usar o babel para compilar seu código no ECMAScript 5, terá acesso a todos os recursos nesta resposta.
obj
duas vezes. Eu acho que criar uma função auxiliar é inevitável? Algo como valores (obj).
Object.values = obj => Object.keys(obj).map(key => obj[key]);
Aqui está uma função reutilizável para obter os valores em uma matriz. Também leva em consideração os protótipos.
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Object
não é um grande problema ( Object.keys
é um calço comum), você provavelmente está pensando em modificar o protótipo de Objeto.
hasOwnProperty()
? Como a chave seria iterada no loop desse objeto que não possui a propriedade?
Se você tiver acesso ao Underscore.js, poderá usar a _.values
função assim:
_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
Se você realmente quer uma matriz de valores, acho isso mais limpo do que construir uma matriz com um loop for ... in.
ECMA 5.1+
function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
Vale a pena notar que, na maioria dos casos, você realmente não precisa de uma matriz de valores, será mais rápido fazer isso:
for(var k in o) something(o[k]);
Isso itera sobre as chaves do Objeto o. Em cada iteração, k é definido como uma chave de o.
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
Você pode percorrer as teclas:
foo = {one:1, two:2, three:3};
for (key in foo){
console.log("foo["+ key +"]="+ foo[key]);
}
irá produzir:
foo[one]=1
foo[two]=2
foo[three]=3
A partir de ECMA2017:
Object.values(obj)
irá buscar todos os valores de propriedade como uma matriz.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Aparentemente - como eu aprendi recentemente - esta é a maneira mais rápida de fazer isso:
var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
// do whatever in here
var obj = objs[objKeys[i]];
}
A pergunta não especifica se também deseja propriedades herdadas e não enumeráveis.
Há uma pergunta para obter tudo, propriedades herdadas e propriedades não enumeráveis também , que o Google não consegue encontrar facilmente.
Minha solução para isso é:
function getAllPropertyNames(obj) {
let result = new Set();
while (obj) {
Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
E então itere sobre eles, basta usar um loop for-of:
Use Object.values()
:, passamos um objeto como argumento e recebemos uma matriz dos valores como valor de retorno.
Isso retorna uma matriz de valores de propriedades enumeráveis próprias de um determinado objeto. Você obterá os mesmos valores usando o for in
loop, mas sem as propriedades no Prototype. Este exemplo provavelmente tornará as coisas mais claras:
function person (name) {
this.name = name;
}
person.prototype.age = 5;
let dude = new person('dude');
for(let prop in dude) {
console.log(dude[prop]); // for in still shows age because this is on the prototype
} // we can use hasOwnProperty but this is not very elegant
// ES6 +
console.log(Object.values(dude));
// very concise and we don't show props on prototype
Aqui está uma função semelhante ao array_values () do PHP
function array_values(input) {
var output = [], key = '';
for ( key in input ) { output[output.length] = input[key]; }
return output;
}
Veja como obter os valores do objeto se você estiver usando o ES6 ou superior:
Array.from(values(obj));
Desde então, Object.values(<object>)
será incorporado no ES7 e
Até esperar todos os navegadores para suportá-lo, você pode envolvê-lo em uma função
Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])
Então :
Object.vals({lastname:'T',firstname:'A'})
// ['T','A']
Object.entries faz isso da melhor maneira.
var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
Object.entries(dataObject).map(itemArray => {
console.log("key=", itemArray[0], "value=", itemArray[1])
})
const myObj = { a:1, b:2, c:3 }
Obtenha todos os valores:
o caminho mais curto:
const myValues = Object.values(myObj)
const myValues = Object.keys(myObj).map(key => myObj[key])
no uso do ECMAScript5
keys = Object.keys(object);
Caso contrário, se o seu navegador não o suportar, use o conhecido for..in loop
for (key in object) {
// your code here
}
object[key]
para obter os valores em um loop.
for..in
(e hasOwnProperty) para que realmente não ganhe nada. Desejo que o ECMAScript 5th seja definido Object.pairs
(e Object.items
para [[key, value], ..]
), mas, infelizmente, isso não acontece.
Agora eu uso o Dojo Toolkit porque navegadores mais antigos não suportam Object.values
.
require(['dojox/lang/functional/object'], function(Object) {
var obj = { key1: '1', key2: '2', key3: '3' };
var values = Object.values(obj);
console.log(values);
});
Resultado :
['1', '2', '3']