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/ assignfunziona: 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 mergefunziona: 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 identicinulllo stesso_.defaultsed _.defaultsDeepelabora gli argomenti in ordine inverso rispetto agli altri (sebbene il primo argomento sia ancora l'oggetto target)_.mergee _.defaultsDeepuniranno gli oggetti figlio e gli altri sovrascriveranno a livello di root_.assigne _.extendsovrascriverà 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" }
_.assigngestisce undefinedma 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" }
nulllo 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 }
_.mergee _.defaultsDeepunirà 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 undefinedvalori:
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 mergenon unirà i undefinedvalori in valori definiti.
mergeIntoavesse proprietà che toMergenon 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.