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

Respuestas:

447

Al usar un for..inbucle simple :

for(var key in objects) {
    var value = objects[key];
}
Tatu Ulmanen
fuente
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.

qubyte
fuente
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;
}
teh_senaus
fuente
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]
jichi
fuente
@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.

zzz
fuente
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]
MrBii
fuente
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
Ariera
fuente
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
Ch.Idea
fuente
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!

usuario40521
fuente
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]];
}
dylnmc
fuente
¿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:

nonopolaridad
fuente
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

Willem van der Veen
fuente
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
priya_21
fuente
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));
jaggedsoft
fuente
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.

Abdennour TOUMI
fuente
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];
  });
};
Jamie
fuente
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])
  })

Mustkeem K
fuente
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])

Anatoliy_Z
fuente
-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }
Sudarshan
fuente
-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
}
usuario278064
fuente
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']
rio
fuente
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

Puneet
fuente