В библиотеке Lodash кто-нибудь может дать лучшее объяснение слияния и расширения / назначения .
Это простой вопрос, но ответ, тем не менее, уклоняется от меня.
В библиотеке Lodash кто-нибудь может дать лучшее объяснение слияния и расширения / назначения .
Это простой вопрос, но ответ, тем не менее, уклоняется от меня.
Ответы:
Вот как extend/ assignработает: Для каждого свойства в источнике скопируйте его значение как есть в место назначения. если значения свойств сами по себе являются объектами, рекурсивного обхода их свойств не происходит. Весь объект будет взят из источника и установлен в место назначения.
Вот как это mergeработает: Для каждого свойства в источнике проверьте, является ли это свойство самим объектом. Если это так, то идите рекурсивно вниз и попытайтесь отобразить свойства дочерних объектов от источника к месту назначения. По сути, мы объединяем иерархию объектов от источника к месту назначения. В то время как для extend/ assignэто простая одноуровневая копия свойств из источника в место назначения.
Вот простой JSBin, который прояснил бы это: http://jsbin.com/uXaqIMa/2/edit?js,console
Вот более сложная версия, которая также включает в себя массив: 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это псевдоним для _.assign, поэтому они идентичныnullодинаково_.defaultsи _.defaultsDeepобрабатывает аргументы в обратном порядке по сравнению с другими (хотя первый аргумент все еще является целевым объектом)_.merge а также _.defaultsDeep объединит дочерние объекты, а остальные перезапишут на корневом уровне_.assign и _.extendперезапишет значение сundefined_.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 ручки undefined но другие пропустят это_.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 одинаково_.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 и _.defaultsDeepбудут сливать дочерние объекты_.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" }
Примечание. Как указывает @Mistic, Lodash рассматривает массивы как объекты, ключи которых являются индексом в массиве.
_.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конфликтует сOnly _.assign will overwrite a value with undefined
Еще одно отличие, на которое следует обратить внимание, это обработка 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}
Так mergeчто не будет объединять undefinedзначения в определенные значения.
mergeIntoнего были свойства, которых у toMergeнего не было, он бы сохранил эти свойства. В этом случае это не был бы клон.
Также может быть полезно рассмотреть то, что они делают с семантической точки зрения:
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.
Я считаю, что изучение этих методов с семантической точки зрения позволит вам лучше «угадать», каково будет поведение для всех различных сценариев существующих и несуществующих ценностей.