Si creo un objeto como este:
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
¿El objeto resultante siempre se verá así?
{ prop1 : "Foo", prop2 : "Bar" }
Es decir, ¿las propiedades estarán en el mismo orden en que las agregué?
javascript
object
suave
fuente
fuente
for-in
,Object.keys
) no tienen que apoyarlo (oficialmente), pero no es para ahora. (Extraoficialmente: Firefox, Chrome y Edge siguen el orden especificado incluso en for-in y Object.keys, donde no están oficialmente obligados a: jsfiddle.net/arhbn3k2/1 )Respuestas:
El orden de iteración para los objetos sigue un cierto conjunto de reglas desde ES2015, pero no (siempre) sigue el orden de inserción . En pocas palabras, el orden de iteración es una combinación del orden de inserción para las teclas de cadenas y el orden ascendente para las teclas numéricas:
Usar una matriz o un
Map
objeto puede ser una mejor manera de lograr esto.Map
comparte algunas similitudesObject
y garantiza que las claves se repitan en orden de inserción , sin excepción:Como nota, el orden de las propiedades en los objetos no estaba garantizado antes de ES2015. Definición de un objeto de ECMAScript Tercera edición (pdf) :
fuente
SÍ (para claves no enteras).
La mayoría de los navegadores iteran las propiedades del objeto como:
Algunos navegadores antiguos combinan las categorías 1 y 2, iterando todas las claves en orden de inserción. Si sus claves pueden analizarse como enteros, es mejor no confiar en ningún orden de iteración específico.
El orden de inserción de la especificación de idioma actual (desde ES2015) se conserva, excepto en el caso de claves que se analizan como enteros (por ejemplo, "7" o "99"), donde el comportamiento varía entre los navegadores. Por ejemplo, Chrome / V8 no respeta el orden de inserción cuando las claves se analizan como numéricas.
Especificación de idioma antiguo (antes de ES2015) : el orden de iteración era técnicamente indefinido, pero todos los principales navegadores cumplían con el comportamiento de ES2015.
Tenga en cuenta que el comportamiento ES2015 fue un buen ejemplo de la especificación del lenguaje impulsada por el comportamiento existente, y no al revés. Para tener una idea más profunda de esa mentalidad de compatibilidad con versiones anteriores, consulte http://code.google.com/p/v8/issues/detail?id=164 , un error de Chrome que cubre en detalle las decisiones de diseño detrás del comportamiento de orden de iteración de Chrome . Según uno de los comentarios (bastante obstinados) sobre ese informe de error:
fuente
createFragment
API ya se basa en esto ... miEl orden de las propiedades en los objetos normales es un tema complejo en Javascript.
Mientras que en ES5 explícitamente no se ha especificado ningún pedido, ES2015 tiene un pedido en ciertos casos. Dado es el siguiente objeto:
Esto resulta en el siguiente orden (en ciertos casos):
Por lo tanto, hay tres segmentos que pueden alterar el orden de inserción (como sucedió en el ejemplo). Y las teclas de tipo entero no se adhieren al orden de inserción en absoluto.
La pregunta es, ¿para qué métodos está garantizado este pedido en la especificación ES2015?
Los siguientes métodos garantizan el orden que se muestra:
Los siguientes métodos / bucles no garantizan ningún orden en absoluto:
Conclusión: incluso en ES2015 no debe confiar en el orden de las propiedades de los objetos normales en Javascript. Es propenso a errores. Usar en su
Map
lugar.fuente
En el momento de la escritura, la mayoría de los navegadores devolvieron las propiedades en el mismo orden en que se insertaron, pero explícitamente no se garantizó el comportamiento, por lo que no debería haber sido utilizado.
La especificación ECMAScript solía decir:
Sin embargo, en ES2015 y posteriores, las claves no enteras se devolverán en orden de inserción.
fuente
Toda esta respuesta está en el contexto del cumplimiento de especificaciones, no lo que hace cualquier motor en un momento particular o históricamente.
En general, no
La pregunta real es muy vaga.
¿En que contexto?
La respuesta es: depende de varios factores. En general, no .
A veces sí
Aquí es donde puede contar con el orden de las claves de propiedad para plain
Objects
:Object.getOwnPropertyNames()
`Reflect.ownKeys()
`Object.getOwnPropertySymbols(O)
En todos los casos, estos métodos incluyen claves de propiedad no enumerables y claves de orden como se especifica en
[[OwnPropertyKeys]]
(ver más abajo). Difieren en el tipo de valores clave que incluyen (String
y / oSymbol
). En este contextoString
incluye valores enteros.Object.getOwnPropertyNames(O)
Devuelve
O
lasString
propiedades con clave propia ( nombres de propiedad ).Reflect.ownKeys(O)
Devuelve
O
las propiedades propiasString
y conSymbol
clave.Object.getOwnPropertySymbols(O)
Devuelve
O
lasSymbol
propiedades de clave propia .[[OwnPropertyKeys]]
El orden es esencialmente: tipo entero
Strings
en orden ascendente, no tipo enteroStrings
en orden de creación, símbolos en orden de creación. Dependiendo de qué función invoque esto, algunos de estos tipos pueden no estar incluidos.El lenguaje específico es que las claves se devuelven en el siguiente orden:
Map
Si está interesado en los mapas ordenados, debería considerar usar el
Map
tipo introducido en ES2015 en lugar de simpleObjects
.fuente
En los navegadores modernos, puede usar la
Map
estructura de datos en lugar de un objeto.Desarrollador mozilla> Mapa
fuente
En ES2015, lo hace, pero no a lo que podrías pensar
El orden de las claves en un objeto no estaba garantizado hasta ES2015. Fue definido por la implementación.
Sin embargo, en ES2015 en se especificó en. Al igual que muchas cosas en JavaScript, esto se hizo con fines de compatibilidad y, en general, reflejaba un estándar no oficial existente entre la mayoría de los motores JS (con una excepción).
El orden se define en la especificación, bajo la operación abstracta OrdinaryOwnPropertyKeys , que sustenta todos los métodos de iteración sobre las propias claves de un objeto. Parafraseado, el orden es el siguiente:
Todos índice entero teclas (cosas por el estilo
"1123"
,"55"
etc) en orden numérico ascendente.Todas las claves de cadena que no son índices enteros, en orden de creación (más antiguo-primero).
Todas las teclas de símbolos, en orden de creación (más antiguo-primero).
Es tonto decir que el pedido no es confiable: es confiable, probablemente no sea lo que desea, y los navegadores modernos implementan este pedido correctamente.
Algunas excepciones incluyen métodos para enumerar claves heredadas, como el
for .. in
bucle. Elfor .. in
bucle no garantiza el orden de acuerdo con las especificaciones.fuente
A partir de ES2015, el orden de las propiedades está garantizado para ciertos métodos que iteran sobre las propiedades. Pero no otros . Desafortunadamente, los métodos que no se garantiza que tengan un pedido son generalmente los más utilizados:
Object.keys
`Object.values
`Object.entries
for..in
buclesJSON.stringify
Pero, a partir de ES2020, el orden de propiedad de estos métodos que anteriormente no eran confiables estará garantizado por la especificación para que se repita de la misma manera determinista que los demás, debido a la propuesta terminada : mecánica for-in .
Al igual que con los métodos que tienen un orden de iteración garantizado (like
Reflect.ownKeys
yObject.getOwnPropertyNames
), los métodos no especificados previamente también iterarán en el siguiente orden:Esto es lo que casi todas las implementaciones ya hacen (y lo han hecho durante muchos años), pero la nueva propuesta lo ha hecho oficial.
Aunque la especificación actual deja ... en orden de iteración " casi totalmente sin especificar , los motores reales tienden a ser más consistentes:"
Debido a que cada implementación ya itera sobre las propiedades de manera predecible, se puede incluir en la especificación sin romper la compatibilidad con versiones anteriores.
Hay algunos casos extraños en los que las implementaciones actualmente no están de acuerdo, y en tales casos, el orden resultante continuará sin especificarse. Para garantizar el orden de la propiedad :
fuente
Como han dicho otros, no tiene garantía en cuanto al orden cuando itera sobre las propiedades de un objeto. Si necesita una lista ordenada de múltiples campos, le sugerí crear una matriz de objetos.
De esta manera, puede usar un bucle for regular y tener el orden de inserción. A continuación, puede utilizar el método de ordenación de matriz para ordenar esto en una nueva matriz si es necesario.
fuente
Acabo de descubrir esto de la manera difícil.
Usando React with Redux, el contenedor de estado de las claves de las cuales quiero atravesar para generar hijos se actualiza cada vez que se cambia la tienda (según los conceptos de inmutabilidad de Redux).
Por lo tanto, para tomar
Object.keys(valueFromStore)
solíaObject.keys(valueFromStore).sort()
, de modo que al menos ahora tengo un orden alfabético para las teclas.fuente
Del estándar JSON :
(énfasis mío).
Entonces, no, no puede garantizar el pedido.
fuente