Na biblioteca Lodash , alguém pode fornecer uma explicação melhor da mesclagem e extensão / atribuição .
É uma pergunta simples, mas a resposta me escapa.
Na biblioteca Lodash , alguém pode fornecer uma explicação melhor da mesclagem e extensão / atribuição .
É uma pergunta simples, mas a resposta me escapa.
Respostas:
Veja como extend
/assign
obras: Para cada propriedade na origem, copie seu valor como está até o destino. se os próprios valores da propriedade são objetos, não há um percurso recursivo de suas propriedades. O objeto inteiro seria retirado da origem e definido no destino.
Eis como merge
funciona: Para cada propriedade na fonte, verifique se essa propriedade é o próprio objeto. Se estiver, desça recursivamente e tente mapear as propriedades do objeto filho da origem ao destino. Então, basicamente, mesclamos a hierarquia de objetos da origem ao destino. Enquanto para extend
/ assign
, é uma cópia simples de um nível das propriedades da origem ao destino.
Aqui está o JSBin simples que deixaria isso bem claro: http://jsbin.com/uXaqIMa/2/edit?js,console
Aqui está uma versão mais elaborada que inclui matriz no exemplo também: 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
é um apelido para _.assign
, então eles são idênticosnull
o mesmo_.defaults
e _.defaultsDeep
processa os argumentos em ordem inversa em comparação com os outros (embora o primeiro argumento ainda seja o objeto de destino)_.merge
e _.defaultsDeep
mesclará objetos filho e os outros substituirão no nível raiz_.assign
e _.extend
substituirá um valor comundefined
_.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
alças, undefined
mas os outros vão pular_.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
o mesmo_.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
mesclará objetos filho_.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: Como o @Mistic apontou, o Lodash trata matrizes como objetos em que as chaves são o índice da matriz.
_.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
conflitos comOnly _.assign will overwrite a value with undefined
Outra diferença a ser observada é a manipulação de undefined
valores:
mergeInto = { a: 1}
toMerge = {a : undefined, b:undefined}
lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined}
lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined}
Portanto merge
, não mesclará undefined
valores em valores definidos.
mergeInto
tivesse propriedades que toMerge
não possuíam, ele as manteria. Nesse caso, não seria um clone.
Também pode ser útil considerar o que eles fazem do ponto de vista semântico:
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.
Acredito que aprender a pensar nesses métodos do ponto de vista semântico permitiria "adivinhar" qual seria o comportamento de todos os diferentes cenários de valores existentes e não existentes.