В библиотеке 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.
Я считаю, что изучение этих методов с семантической точки зрения позволит вам лучше «угадать», каково будет поведение для всех различных сценариев существующих и несуществующих ценностей.