Nella libreria Lodash , qualcuno può fornire una spiegazione migliore di unire ed estendere / assegnare .
È una domanda semplice ma la risposta mi sfugge comunque.
Nella libreria Lodash , qualcuno può fornire una spiegazione migliore di unire ed estendere / assegnare .
È una domanda semplice ma la risposta mi sfugge comunque.
Risposte:
Ecco come extend
/ assign
funziona: per ogni proprietà nell'origine, copia il suo valore così com'è nella destinazione. se i valori delle proprietà stessi sono oggetti, non c'è attraversamento ricorsivo delle loro proprietà. L'intero oggetto verrebbe prelevato dall'origine e impostato sulla destinazione.
Ecco come merge
funziona: per ogni proprietà nell'origine, controlla se quella proprietà è l'oggetto stesso. In tal caso, riduci in modo ricorsivo e prova a mappare le proprietà dell'oggetto figlio dall'origine alla destinazione. Quindi essenzialmente fondiamo la gerarchia di oggetti dall'origine alla destinazione. Mentre per extend
/ assign
, è semplice copia di un livello delle proprietà dall'origine alla destinazione.
Ecco JSBin semplice che chiarirebbe questo aspetto: http://jsbin.com/uXaqIMa/2/edit?js,console
Ecco la versione più elaborata che include anche l'array nell'esempio: http://jsbin.com/uXaqIMa/1/edit?js,console
var combined = merge({}, src, dest)
_.merge(object, [sources], [customizer], [thisArg])
_.assign(object, [sources], [customizer], [thisArg])
_.extend(object, [sources], [customizer], [thisArg])
_.defaults(object, [sources])
_.defaultsDeep(object, [sources])
_.extend
è un alias per _.assign
, quindi sono identicinull
lo stesso_.defaults
ed _.defaultsDeep
elabora gli argomenti in ordine inverso rispetto agli altri (sebbene il primo argomento sia ancora l'oggetto target)_.merge
e _.defaultsDeep
uniranno gli oggetti figlio e gli altri sovrascriveranno a livello di root_.assign
e _.extend
sovrascriverà un valore conundefined
_.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
gestisce undefined
ma gli altri lo salteranno_.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" }
null
lo stesso_.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 }
_.merge
e _.defaultsDeep
unirà gli oggetti figlio_.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" }}
_.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" ] }
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" }
Nota: come sottolineato da @Mistic, Lodash considera gli array come oggetti in cui le chiavi sono l'indice dell'array.
_.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" ]
_.extend is an alias for _.assign, so they are identical
è in conflitto conOnly _.assign will overwrite a value with undefined
Un'altra differenza a cui prestare attenzione è la gestione dei undefined
valori:
mergeInto = { a: 1}
toMerge = {a : undefined, b:undefined}
lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined}
lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined}
Quindi merge
non unirà i undefined
valori in valori definiti.
mergeInto
avesse proprietà che toMerge
non avevano, avrebbe mantenuto quelle proprietà. In tal caso non sarebbe un clone.
Potrebbe anche essere utile considerare cosa fanno da un punto di vista semantico:
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)
merge is like assign but does not assign objects but replicates them instead.
(deep copy)
provides default values for missing values.
so will assign only values for keys that do not exist yet in the source.
works like _defaults but like merge will not simply copy objects
and will use recursion instead.
Credo che imparare a pensare a quei metodi dal punto di vista semantico ti permetterebbe di "indovinare" meglio quale sarebbe il comportamento per tutti i diversi scenari di valori esistenti e non esistenti.