Digamos que tengo una options
variable y quiero establecer algún valor predeterminado.
¿Cuál es el beneficio / inconveniente de estas dos alternativas?
Usando propagación de objetos
options = {...optionsDefault, ...options};
O usando Object.assign
options = Object.assign({}, optionsDefault, options);
Este es el compromiso que me hizo preguntarme.
javascript
ecmascript-6
Olivier Tassinari
fuente
fuente
Respuestas:
Esto no es necesariamente exhaustivo.
Sintaxis extendida
Ventajas:
Si crea código para su ejecución en entornos sin soporte nativo, es posible que pueda compilar esta sintaxis (en lugar de usar un polyfill). (Con Babel, por ejemplo).
Menos detallado.
Desventajas
Cuando esta respuesta se escribió originalmente, se trataba de una propuesta , no estandarizada. Cuando use propuestas, considere lo que haría si escribe código con él ahora y no se estandariza o cambia a medida que avanza hacia la estandarización. Desde entonces, esto se ha estandarizado en ES2018.
Literal, no dinámico.
Object.assign()
Ventajas:
Estandarizado.
Dinámica. Ejemplo:
Desventajas
Eso no está directamente relacionado con lo que estás preguntando. Ese código no estaba usando
Object.assign()
, estaba usando el código de usuario (object-assign
) que hace lo mismo. Parece que compilan ese código con Babel (y lo agrupan con Webpack), que es de lo que estaba hablando: la sintaxis que puedes compilar. Aparentemente prefirieron eso a tener que incluirloobject-assign
como una dependencia que iría en su construcción.fuente
Object.assign()
. O puede iterar manualmente sobre una matriz de objetos y sus propios accesorios asignándolos manualmente a un objetivo y hacerlo aún más detallado: PPara el objeto de referencia, el reposo / propagación se finaliza en ECMAScript 2018 como una etapa 4. La propuesta se puede encontrar aquí .
En su mayor parte, el restablecimiento y la propagación de objetos funcionan de la misma manera, la diferencia clave es que la propagación define las propiedades, mientras que Object.assign () las establece . Esto significa que Object.assign () activa los establecedores.
Vale la pena recordar que, aparte de esto, el objeto rest / spread 1: 1 se asigna a Object.assign () y actúa de manera diferente a la matriz (iterable) spread. Por ejemplo, cuando se extiende una matriz, los valores nulos se extienden. Sin embargo, el uso de objetos con valores nulos se extiende silenciosamente a nada.
Ejemplo de dispersión de matriz (Iterable)
Ejemplo de dispersión de objetos
Esto es coherente con cómo funcionaría Object.assign (), ambos excluyen silenciosamente el valor nulo sin error.
fuente
Object.assign
usará setters.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
vs.{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. En cuyo caso, que yo sepa, quisiéramos ver el comportamiento al igual que la matriz://{a: 1, b: 2, c: null}
.Creo que una gran diferencia entre el operador de propagación y
Object.assign
que no parece mencionarse en las respuestas actuales es que el operador de propagación no copiará el prototipo del objeto de origen al objeto de destino. Si desea agregar propiedades a un objeto y no desea cambiar de qué instancia es, entonces deberá usarloObject.assign
. El siguiente ejemplo debería demostrar esto:fuente
errorExtendedUsingAssign === error
peroerrorExtendedUsingSpread
es un objeto nuevo (y el prototipo no se copió).let target = Object.create(source); Object.assign(target, source);
Como otros han mencionado, en este momento de la escritura, se
Object.assign()
requiere un polyfill y la propagación de objetos...
requiere algo de transpiling (y quizás un polyfill también) para funcionar.Considera este código:
Ambos producen la misma salida.
Aquí está la salida de Babel, a ES5:
Este es mi entendimiento hasta ahora.
Object.assign()
en realidad está estandarizado, donde la dispersión de objetos...
aún no está El único problema es el soporte del navegador para el primero y en el futuro, el segundo también.Juega con el código aquí
Espero que esto ayude.
fuente
{}
debería corregir la inconsistencia.El operador de propagación de objetos (...) no funciona en los navegadores, porque todavía no forma parte de ninguna especificación de ES, solo una propuesta. La única opción es compilarlo con Babel (o algo similar).
Como puede ver, es solo azúcar sintáctico sobre Object.assign ({}).
Hasta donde puedo ver, estas son las diferencias importantes.
...
para objetos no está estandarizado...
te protege de mutar accidentalmente el objeto...
polyfill Object.assign en navegadores sin él...
necesita menos código para expresar la misma ideafuente
Object.assign
, como el operador de difusión siempre te dará un nuevo objeto.Me gustaría resumir el estado de la función ES de "fusión de objetos distribuidos", en navegadores y en el ecosistema a través de herramientas.
Especificaciones
Navegadores: en Chrome, en SF, Firefox pronto (ver 60, IIUC)
Herramientas: Nodo 8.7, TS 2.1
Enlaces
Muestra de código (funciona como prueba de compatibilidad)
De nuevo: al momento de escribir este ejemplo, funciona sin transpilación en Chrome (60+), Firefox Developer Edition (versión preliminar de Firefox 60) y Node (8.7+).
¿Por qué responder?
Estoy escribiendo esto 2.5 años después de la pregunta original. Pero tenía la misma pregunta, y aquí es donde me envió Google. Soy un esclavo de la misión de SO de mejorar la larga cola.
Dado que esta es una expansión de la sintaxis de "dispersión de matriz", encontré que es muy difícil para google y difícil de encontrar en las tablas de compatibilidad. Lo más cercano que pude encontrar es Kangax "spread de propiedad" , pero esa prueba no tiene dos spreads en la misma expresión (no una fusión). Además, el nombre en las páginas de propuestas / borradores / estado del navegador usa "propagación de propiedad", pero me parece que fue un "primer director" al que llegó la comunidad después de las propuestas para usar la sintaxis de propagación para "fusión de objetos". (Lo que podría explicar por qué es tan difícil buscar en Google). Así que documento mi hallazgo aquí para que otros puedan ver, actualizar y compilar enlaces sobre esta característica específica. Espero que se ponga de moda. Ayude a difundir la noticia de que aterriza en las especificaciones y en los navegadores.
Por último, habría agregado esta información como comentario, pero no podría editarla sin romper la intención original de los autores. Específicamente, no puedo editar el comentario de @ ChillyPenguin sin que pierda su intención de corregir a @RichardSchulte. Pero años después, Richard resultó tener razón (en mi opinión). Así que escribo esta respuesta en su lugar, con la esperanza de que eventualmente gane fuerza sobre las respuestas antiguas (podría tomar años, pero de eso se trata el efecto de cola larga , después de todo).
fuente
NOTA: Spread NO es solo azúcar sintáctico alrededor de Object.assign. Operan de manera muy diferente detrás de escena.
Object.assign aplica setters a un nuevo objeto, Spread no. Además, el objeto debe ser iterable.
Copiar Use esto si necesita el valor del objeto tal como está en este momento, y no desea que ese valor refleje los cambios realizados por otros propietarios del objeto.
Úselo para crear una copia superficial del objeto, una buena práctica para establecer siempre propiedades inmutables para copiar, ya que las versiones mutables se pueden pasar a propiedades inmutables, la copia garantizará que siempre esté tratando con un objeto inmutable
Asignar Asignar es algo opuesto a copiar. Asignar generará un setter que asigna el valor a la variable de instancia directamente, en lugar de copiarlo o retenerlo. Al llamar al captador de una propiedad de asignación, devuelve una referencia a los datos reales.
fuente
Otras respuestas son viejas, no se pudo obtener una buena respuesta.
El siguiente ejemplo es para literales de objeto, ayuda a que ambos puedan complementarse entre sí y cómo no pueden complementarse entre sí (por lo tanto, la diferencia):
Varios ejemplos más pequeños aquí, también para matriz y objeto:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
fuente
Esto ahora es parte de ES6, por lo tanto, está estandarizado y también está documentado en MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Es muy conveniente de usar y tiene mucho sentido junto con la desestructuración de objetos.
La ventaja restante que se menciona anteriormente es la capacidad dinámica de Object.assign (), sin embargo, esto es tan fácil como distribuir la matriz dentro de un objeto literal. En la salida compilada de babel, usa exactamente lo que se demuestra con Object.assign ()
Por lo tanto, la respuesta correcta sería usar la distribución de objetos, ya que ahora está estandarizada, se usa ampliamente (ver react, redux, etc.), es fácil de usar y tiene todas las características de Object.assign ()
fuente
Me gustaría agregar este ejemplo simple cuando tienes que usar Object.assign.
No puede quedar claro cuando usas JavaScript. Pero con TypeScript es más fácil si desea crear una instancia de alguna clase
fuente