¿Algún punto en el uso de ES6 Map cuando las teclas son todas cadenas?

36

Las claves de objetos simples deben ser cadenas, mientras que una Mappuede tener claves de cualquier tipo.

Pero tengo poco uso para esto en la práctica. En casi todos los casos, me encuentro usando cadenas como teclas de todos modos. Y presumiblemente new Map()es más lento que {}. Entonces, ¿hay alguna otra razón por la que podría ser mejor usar un objeto en Maplugar de un simple?

callum
fuente
3
MDN , como siempre, tiene una buena comparación.
Chris Hayes
1
Para su información, el mapa parece ser más rápido para configurar y obtener.
mpen
@mpen - jsperf está caído ahora. ¿Está seguro de que se map.set('foo', 123)realizó más rápido que obj.foo = 123? Si es así, eso es muy sorprendente
callum
@callum Uhh..no, no es positivo. Es posible que desee escribir algunas nuevas pruebas de rendimiento.
mpen

Respuestas:

42

Hay algunas razones por las que prefiero usar Maps sobre objetos simples ( {}) para almacenar datos de tiempo de ejecución (cachés, etc.):

  1. La .sizepropiedad me permite saber cuántas entradas existen en este Mapa;
  2. Los diversos métodos de utilidad - .clear(), .forEach(), etc;
  3. ¡Me proporcionan iteradores por defecto!

Todos los demás casos, como pasar argumentos de funciones, almacenar configuraciones, etc., se escriben utilizando objetos simples.

Además, recuerde: no intente optimizar su código demasiado pronto. No pierda su tiempo haciendo puntos de referencia de objetos simples frente a Maps a menos que su proyecto esté sufriendo problemas de rendimiento.

gustavohenke
fuente
1
¿Cuál es la función de hashcode de identidad utilizada por Javascript?
Pacerier
1
@Pacerier ===:)
gustavohenke
Los mapas son mucho más rápidos que los objetos simples en estos días.
jayarjo
@gustavohenke Eso no es cierto. Mapusa el algoritmo SameValueZero. developer.mozilla.org/en-US/docs/Web/JavaScript/…
lolmaus - Andrey Mikhaylov
@ lolmaus-AndreyMikhaylov está bien, pero ¿dije algo acerca de Maps usando esto o aquello?
gustavohenke
4

No estoy seguro de esto, pero creo que el rendimiento NO es una razón para usar Maps. Eche un vistazo a esta página actualizada de jsperf:

http://jsperf.com/es6-map-vs-object-properties/73

Parece que (cuando se trata de cadenas al menos) los objetos son mucho más rápidos que los mapas para la configuración básica y la obtención.

starlogodaniel
fuente
2
Así no es como se escriben las pruebas de rendimiento.
Qix
66
No es así como escribes comentarios útiles. Por favor, siéntase libre de elaborar si tiene una metodología alternativa para sugerir. ¿Qué tiene de malo específicamente cómo se escribieron esas pruebas? ¿Son de alguna manera inválidos o inútiles?
starlogodaniel
99
La semántica / construcción del lenguaje que se prueba mediante microbenchmarks solo debe diferir en una variable. Sus pruebas varían según el número de iteraciones, y algunas de ellas tendrán su contenido de bucle interno optimizado ya que el resultado no se utiliza. Algunas pruebas pre declaran variables, mientras que otras tienen la declaración de variables en línea con el bucle for, lo que puede generar diferentes anomalías de rendimiento.
Qix
1
Ouch, tienes toda la razón. En mi defensa, mi versión fue una mejora con respecto a la anterior, pero me perdí tanto el contenido de la declaración previa como el contenido del bucle interno que se optimizó. Estaba trabajando con un colega que mejoró mi borrador y creo que resolvió esos problemas: jsperf.com/es6-map-vs-object-properties/88 . Sin embargo, creo que es válido tener diferentes estilos de bucle para las diferentes estructuras de datos; en uso real, las personas elegirán la estructura de bucle con el mejor rendimiento, y Map y Object tienen diferentes estructuras de bucle "óptimas". De todos modos, gracias por la captura.
starlogodaniel
Ok, ahora veo: solían ser más lentos que los objetos simples, pero se han optimizado mucho en los navegadores recientes.
jayarjo
0

Las otras respuestas no mencionan una última diferencia entre objetos Mapys:

El Mapobjeto contiene pares clave-valor y recuerda el orden de inserción original de las claves .

Por lo tanto, al iterar sobre él, un objeto Map devuelve claves en orden de inserción.

Cita de MDN , énfasis mío


Esta fue la razón principal por la que decidí usar Mappor primera vez en un proyecto reciente. Tenía un objeto normal que necesitaba mostrar en un <table>, con cada propiedad yendo en una fila específica.

let productPropertyOrder = [ "name", "weight", "price", "stocked" ];

let product =
{
    name: "Lasagne",
    weight: "1kg",
    price: 10,
    stocked: true
}

Escribí una función para transformar un objeto en un Maporden de teclas deseado:

function objectToMap( obj, order )
{
    let map = new Map();

    for ( const key of order )
    {
        if ( obj.hasOwnProperty( key ) )
        {
            map.set( key, obj[ key ] );
        }
    }

    return map;
}

Luego, el mapa podría repetirse en el orden deseado:

let productMap = objectToMap( product, productPropertyOrder );

for ( const value of productMap.values() )
{
    let cell = document.createElement( "td" );
    cell.innerText = value;
    row.appendChild( cell );
}

Por supuesto, esto es un poco artificial porque uno podría mostrarse al iterar sobre el orden de las propiedades sin crear un Mapen el proceso:

for ( const key of productPropertyOrder )
{
    if ( product.hasOwnProperty( key ) )
    {
        let value = product[ key ];
        // create cell
    }
}

Pero si tiene una variedad de tales objetos y los va a mostrar en muchos lugares, entonces convertirlos a mapas primero tiene sentido.

WD40
fuente