¿Cómo obtener todos los valores de propiedades de un objeto JavaScript (sin conocer las claves)?


455

Si hay un objeto Javascript:

var objects={...};

Supongamos que tiene más de 50 propiedades, sin conocer los nombres de las propiedades (es decir, sin conocer las 'claves'), ¿cómo obtener cada valor de propiedad en un bucle?


23
Nota para los lectores: no te pierdas la muy perspicaz segunda respuesta
Pandaiolo

Respuestas:


447

Al usar un for..inbucle simple :

for(var key in objects) {
    var value = objects[key];
}

90
Tenga cuidado con las propiedades del objeto prototipo que se hereda. Ver: hasOwnProperty ()
oliva

102
Si está leyendo esta respuesta, definitivamente debería leer la otra
mgarciaisaia

18
Si está leyendo esta respuesta y posiblemente esté lidiando con cadenas, definitivamente debería golpear javascript en la cara.

Si lees la respuesta anterior y quieres golpear JavaScript en la cara, prueba lodash
slugmandrew

Probablemente debería señalar que esto NO incluirá propiedades que tengan su enumerablebandera establecida en falso. Esto, entre otras cosas, significa que no iterará sobre ningún método de clase, sino que iterará sobre métodos creados de otras maneras.
rico remer

1012

Dependiendo de qué navegadores tenga que admitir, esto se puede hacer de varias maneras. La abrumadora mayoría de los navegadores en la naturaleza admite ECMAScript 5 (ES5), pero tenga en cuenta que muchos de los ejemplos a continuación utilizan Object.keys, que no está disponible en IE <9. Consulte la tabla de compatibilidad .

ECMAScript 3+

Si tiene que admitir versiones anteriores de IE, esta es la opción para usted:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}

El anidado ifse asegura de que no enumere las propiedades en la cadena de prototipos del objeto (que es el comportamiento que seguramente desea). Debes usar

Object.prototype.hasOwnProperty.call(obj, key) // ok

más bien que

obj.hasOwnProperty(key) // bad

porque ECMAScript 5+ te permite crear objetos sin prototipos con Object.create(null) , y estos objetos no tendrán el hasOwnPropertymétodo. El código travieso también puede producir objetos que anulan el hasOwnPropertymétodo.

ECMAScript 5+

Puede utilizar estos métodos en cualquier navegador que admita ECMAScript 5 y superior. Estos obtienen valores de un objeto y evitan enumerarlos en la cadena del prototipo. ¿Dónde objestá tu objeto?

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}

Si quieres algo un poco más compacto o quieres tener cuidado con las funciones en bucles, entonces Array.prototype.forEaches tu amigo:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

El siguiente método crea una matriz que contiene los valores de un objeto. Esto es conveniente para recorrer.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array

Si desea hacer que los que usan estén Object.keysseguros contra null(como for-inestá), puede hacerlo Object.keys(obj || {})....

Object.keysdevuelve propiedades enumerables . Para iterar sobre objetos simples, esto suele ser suficiente. Si tiene algo con propiedades no enumerables con las que necesita trabajar, puede usarlo Object.getOwnPropertyNamesen lugar de Object.keys.

ECMAScript 2015+ (AKA ES6)

Las matrices son más fáciles de iterar con ECMAScript 2015. Puede usar esto para su ventaja cuando trabaje con valores uno por uno en un bucle:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

Usando las funciones de flecha gruesa ECMAScript 2015, mapear el objeto a una matriz de valores se convierte en una línea:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

Presenta ECMAScript 2015 Symbol, cuyas instancias pueden usarse como nombres de propiedad. Para obtener los símbolos de un objeto para enumerarlos, use Object.getOwnPropertySymbols(esta función es la razón por la cual Symbol no se puede usar para hacer propiedades privadas). La nueva ReflectAPI de ECMAScript 2015 proporciona Reflect.ownKeys, que devuelve una lista de nombres de propiedades (incluidos los no enumerables) y símbolos.

Comprensiones de matriz (no intente usar)

Se eliminaron las comprensiones de matriz de ECMAScript 6 antes de la publicación. Antes de su eliminación, una solución habría parecido:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

ECMAScript 2016 agrega características que no afectan este tema. La especificación ECMAScript 2017 agrega Object.valuesy Object.entries. Ambas matrices de retorno (lo que será sorprendente para algunos dada la analogía con Array.entries). Object.valuesse puede usar tal cual o con un for-ofbucle.

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

Si desea utilizar tanto la clave como el valor, entonces Object.entrieses para usted. Produce una matriz llena de [key, value]pares. Puede usar esto como está o (observe también la asignación de desestructuración de ECMAScript 2015) en un for-ofbucle:

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values calce

Finalmente, como se señaló en los comentarios y por teh_senaus en otra respuesta, puede valer la pena usar uno de estos como un calce. No se preocupe, lo siguiente no cambia el prototipo, solo agrega un método Object(que es mucho menos peligroso). Usando las funciones de flecha gruesa, esto también se puede hacer en una línea:

Object.values = obj => Object.keys(obj).map(key => obj[key]);

que ahora puedes usar como

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });

Si desea evitar el calce cuando Object.valuesexiste un nativo , puede hacer lo siguiente:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

Finalmente...

Tenga en cuenta los navegadores / versiones que necesita admitir. Lo anterior es correcto donde se implementan los métodos o las características del lenguaje. Por ejemplo, el soporte para ECMAScript 2015 se desactivó de forma predeterminada en V8 hasta hace poco, lo que alimentó navegadores como Chrome. Las características de ECMAScript 2015 deben evitarse hasta que los navegadores que intente admitir implementen las características que necesita. Si usa babel para compilar su código en ECMAScript 5, entonces tiene acceso a todas las funciones de esta respuesta.


99
Esta debería ser la respuesta aceptada (o al menos más votada) ya que la respuesta aceptada está incompleta (@olive señala esto).
0xc0de

Es una pena que de todos los llamados trucos, todavía tenemos que mencionar objdos veces. ¿Supongo que crear una función auxiliar es inevitable? Algo parecido a los valores (obj).
Steven Haryanto

Cualquiera de estos métodos puede usarse como una cuña. Por ejemplo:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
Las soluciones ECMA 5 deberían funcionar en todos los navegadores modernos. ECMA 6 aún no se ha finalizado, y el soporte es preliminar en todos los navegadores. En Chrome, ECMA 6 está parcialmente implementado pero deshabilitado. En Firefox, el soporte es mejor, pero la comprensión de la matriz es incorrecta (como se mencionó). Pensé que mi uso del tiempo futuro implicaría esto. @JacekLampart, ¿qué solución le dio el error?
qubyte

2
No puedo imaginar por qué tenemos que esperar a que ES2017 obtenga un método Object.values ​​().
Herbertusz

31

Aquí hay una función reutilizable para obtener los valores en una matriz. También tiene en cuenta los prototipos.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.push(obj[key]);
        }
    }
    return vals;
}

15
La modificación Objectno es un gran problema ( Object.keyses una cuña común), probablemente esté pensando en modificar el prototipo de Objeto.
Sandstrom

¿Por qué necesitarías hacer una prueba hasOwnProperty()? ¿Cómo se iteraría la clave dentro del bucle de ese objeto que no tiene la propiedad?
1252748

44
Google it @ thomas, es importante. Puede tener propiedades de su cadena prototipo.
Joe

28

Si tiene acceso a Underscore.js, puede usar la _.valuesfunción de esta manera:

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]

@MathieuAmiot: ¿te gustaría explicarlo?
Paden

lodash es un reemplazo compatible con api para subrayar, uno (mucho) más rápido.
Mathieu Amiot

@Paden aquí hay una pregunta relacionada sobre SO: stackoverflow.com/questions/13789618/…
jichi

2
lodash es innecesario para esto y aumentará su código base
dman

14

Si realmente desea una matriz de valores, encuentro esto más limpio que construir una matriz con un bucle for ... in.

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

Vale la pena señalar que en la mayoría de los casos realmente no necesita una matriz de valores, será más rápido hacer esto:

for(var k in o) something(o[k]);

Esto itera sobre las claves del objeto o. En cada iteración, k se establece en una clave de o.


9

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]

3
¿Por qué se ha rechazado esto? Yo diría que esta es una de las soluciones más limpias.
Sebastian Hojas

No sé, ¿por qué se vota esto? Esta es la solución más fácil y pura en js sin usar ninguna biblioteca ni ninguna otra utilidad.
sanjeev shetty

5

Puede recorrer las teclas:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

dará salida:

foo[one]=1
foo[two]=2
foo[three]=3

2
También debe marcar `hasOwnProperty () 'si desea evitar los atributos heredados.
0xc0de

3

Para aquellos que se adaptaron temprano en la era de CofeeScript, aquí hay otro equivalente para ello.

val for key,val of objects

Lo que puede ser mejor que esto porque objectsse puede reducir para volver a escribir y disminuir la legibilidad.

objects[key] for key of objects

3

use un polyfill como:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

luego usa

Object.values(my_object)

3) beneficio!



2

Aparentemente, como aprendí recientemente, esta es la forma más rápida de hacerlo:

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]];
}

¿Puedes poner un codepen o jsfiddle de un ejemplo de esto? Gracias.
Chris22

2

La pregunta no especifica si también se desean propiedades heredadas y no enumerables.

Hay una pregunta para obtener todo, propiedades heredadas y propiedades no enumerables también , que Google no puede encontrar fácilmente.

Mi solución para eso es:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

Y luego iterar sobre ellos, solo use un bucle for-of:


1

Utilizar: Object.values() pasamos un objeto como argumento y recibimos una matriz de valores como valor de retorno.

Esto devuelve una matriz de valores de propiedad enumerables propios de un objeto dado. Obtendrá los mismos valores que al usar el for inbucle pero sin las propiedades del prototipo. Este ejemplo probablemente aclarará las cosas:

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


1
const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

0

Aquí hay una función similar a los array_values ​​() de PHP

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

Aquí le mostramos cómo obtener los valores del objeto si está utilizando ES6 o superior:

Array.from(values(obj));

Por alguna razón, values ​​() funciona en Chrome y Firefox, pero no en iojs / node.
jaggedsoft

0

Compatible con ES7, incluso algunos navegadores aún no lo admiten.

Desde entonces, Object.values(<object>)estará integrado en ES7 y

Hasta que espere que todos los navegadores lo admitan, puede incluirlo dentro de una función:

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

Entonces :

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

Una vez que los navegadores sean compatibles con ES7, no tendrá que cambiar nada en su código.


0

Me doy cuenta de que llego un poco tarde, pero aquí hay una cuña para el nuevo Object.valuesmétodo Firefox 47

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};

0

Object.entries lo hace de mejor manera.

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })


0

const myObj = { a:1, b:2, c:3 }

Obtenga todos los valores:

  • El camino más corto:

    • const myValues = Object.values(myObj)
  • const myValues = Object.keys(myObj).map(key => myObj[key])


-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

-5

en uso ECMAScript5

 keys = Object.keys(object);

De lo contrario, si su navegador no lo admite, use el conocido for..in loop

for (key in object) {
    // your code here
}

17
La pregunta era pedir los valores, no las claves.
zachelrath

@zachelrath Tienes razón. - Pero este script es útil si desea obtener los valores porque cuando conoce las claves que puede usar object[key]para obtener los valores en un bucle.
fridojet

2
@fridojet Pero eso se puede hacer con for..in(y hasOwnProperty) para que realmente no gane nada ... Desearía que ECMAScript 5th definiera Object.pairs(y Object.itemspara [[key, value], ..]), pero, por desgracia, no lo hace.
user2246674

-8

Ahora uso Dojo Toolkit porque los navegadores más antiguos no son compatibles 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);
});

Salida:

['1', '2', '3']

55
Estrictamente hablando, la matriz no es correcta. Tiene una matriz de cadenas en lugar de una matriz de números.
Qubyte

-10

utilizar

console.log(variable)

y si usas Google Chrome, abre la consola usando Ctrl + Shift + j

Ir a >> Consola

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.