javascript - remove - lodash object to array
Lodash-diferencia entre.extend()/.assign() y.merge() (4)
En la biblioteca de Lodash , alguien puede proporcionar una mejor explicación de merge y extender / asignar .
Es una pregunta simple pero la respuesta me evade, no obstante.
Lodash versión 3.10.1
Métodos comparados
-
_.merge(object, [sources], [customizer], [thisArg])
-
_.assign(object, [sources], [customizer], [thisArg])
-
_.extend(object, [sources], [customizer], [thisArg])
-
_.defaults(object, [sources])
-
_.defaultsDeep(object, [sources])
Similitudes
- Ninguno de ellos trabaja en arreglos como cabría esperar.
-
_.extend
es un alias para_.assign
, por lo que son idénticos - Todos ellos parecen modificar el objeto objetivo (primer argumento)
- Todos ellos manejan
null
igual.
Diferencias
-
_.defaults
y_.defaultsDeep
procesan los argumentos en orden inverso en comparación con los otros (aunque el primer argumento sigue siendo el objeto de destino) -
_.merge
y_.defaultsDeep
fusionarán objetos secundarios y los demás se sobrescribirán en el nivel raíz - Solo
_.assign
y_.extend
sobrescribirán un valor conundefined
Pruebas
Todos manejan miembros en la raíz de manera similar.
_.assign ({}, { a: ''a'' }, { a: ''bb'' }) // => { a: "bb" }
_.merge ({}, { a: ''a'' }, { a: ''bb'' }) // => { a: "bb" }
_.defaults ({}, { a: ''a'' }, { a: ''bb'' }) // => { a: "a" }
_.defaultsDeep({}, { a: ''a'' }, { a: ''bb'' }) // => { a: "a" }
_.assign
maneja undefined
pero los demás lo omitirán
_.assign ({}, { a: ''a'' }, { a: undefined }) // => { a: undefined }
_.merge ({}, { a: ''a'' }, { a: undefined }) // => { a: "a" }
_.defaults ({}, { a: undefined }, { a: ''bb'' }) // => { a: "bb" }
_.defaultsDeep({}, { a: undefined }, { a: ''bb'' }) // => { a: "bb" }
Todos ellos manejan null
igual.
_.assign ({}, { a: ''a'' }, { a: null }) // => { a: null }
_.merge ({}, { a: ''a'' }, { a: null }) // => { a: null }
_.defaults ({}, { a: null }, { a: ''bb'' }) // => { a: null }
_.defaultsDeep({}, { a: null }, { a: ''bb'' }) // => { a: null }
Pero solo _.merge
y _.defaultsDeep
fusionarán objetos secundarios
_.assign ({}, {a:{a:''a''}}, {a:{b:''bb''}}) // => { "a": { "b": "bb" }}
_.merge ({}, {a:{a:''a''}}, {a:{b:''bb''}}) // => { "a": { "a": "a", "b": "bb" }}
_.defaults ({}, {a:{a:''a''}}, {a:{b:''bb''}}) // => { "a": { "a": "a" }}
_.defaultsDeep({}, {a:{a:''a''}}, {a:{b:''bb''}}) // => { "a": { "a": "a", "b": "bb" }}
Y ninguno de ellos combinará matrices, parece
_.assign ({}, {a:[''a'']}, {a:[''bb'']}) // => { "a": [ "bb" ] }
_.merge ({}, {a:[''a'']}, {a:[''bb'']}) // => { "a": [ "bb" ] }
_.defaults ({}, {a:[''a'']}, {a:[''bb'']}) // => { "a": [ "a" ] }
_.defaultsDeep({}, {a:[''a'']}, {a:[''bb'']}) // => { "a": [ "a" ] }
Todos modifican el objeto objetivo.
a={a:''a''}; _.assign (a, {b:''bb''}); // a => { a: "a", b: "bb" }
a={a:''a''}; _.merge (a, {b:''bb''}); // a => { a: "a", b: "bb" }
a={a:''a''}; _.defaults (a, {b:''bb''}); // a => { a: "a", b: "bb" }
a={a:''a''}; _.defaultsDeep(a, {b:''bb''}); // a => { a: "a", b: "bb" }
Ninguno realmente funciona como se espera en matrices
Nota: Como lo señaló @Mistic, Lodash trata los arreglos como objetos donde las claves son el índice dentro del arreglo.
_.assign ([], [''a''], [''bb'']) // => [ "bb" ]
_.merge ([], [''a''], [''bb'']) // => [ "bb" ]
_.defaults ([], [''a''], [''bb'']) // => [ "a" ]
_.defaultsDeep([], [''a''], [''bb'']) // => [ "a" ]
_.assign ([], [''a'',''b''], [''bb'']) // => [ "bb", "b" ]
_.merge ([], [''a'',''b''], [''bb'']) // => [ "bb", "b" ]
_.defaults ([], [''a'',''b''], [''bb'']) // => [ "a", "b" ]
_.defaultsDeep([], [''a'',''b''], [''bb'']) // => [ "a", "b" ]
Otra diferencia a la que hay que prestar atención es el manejo de valores undefined
:
mergeInto = { a: 1}
toMerge = {a : undefined, b:undefined}
lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined}
lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined}
Así que la merge
no fusionará valores undefined
en valores definidos.
También podría ser útil considerar lo que hacen desde un punto de vista semántico:
_.asignar
will assign the values of the properties of its second parameter and so on,
as properties with the same name of the first parameter. (shallow copy & override)
_.unir
merge is like assign but does not assign objects but replicates them instead.
(deep copy)
_.defaults
provides default values for missing values.
so will assign only values for keys that do not exist yet in the source.
_.defaultsDeep
works like _defaults but like merge will not simply copy objects
and will use recursion instead.
Creo que aprender a pensar en esos métodos desde el punto de vista semántico le permitiría "adivinar" cuál sería el comportamiento para todos los diferentes escenarios de valores existentes y no existentes.
Aquí es cómo funciona extend
/ assign
: Para cada propiedad en la fuente, copie su valor como está al destino. Si los valores de propiedad en sí son objetos, no hay recorrido recursivo de sus propiedades. Todo el objeto se tomaría del origen y se establecería en destino.
Así es como funciona la merge
: para cada propiedad en la fuente, verifique si esa propiedad es un objeto en sí. Si es así, vaya de forma recursiva e intente asignar las propiedades del objeto secundario desde el origen hasta el destino. Así que esencialmente fusionamos la jerarquía de objetos desde el origen hasta el destino. Mientras que para extend
/ assign
, es una copia simple de propiedades de un origen a destino.
Aquí hay un simple JSBin que lo dejaría claro: http://jsbin.com/uXaqIMa/2/edit?js,console
Aquí hay una versión más elaborada que también incluye la matriz en el ejemplo: http://jsbin.com/uXaqIMa/1/edit?js,console