Lodash - difference between .extend() / .assign() and .merge()
在Lodash库中,是否可以有人更好地解释合并和扩展/分配。
这是一个简单的问题,但我还是没有回答。
下面是
下面是
下面是一个简单的jsbin,它将使这个水晶清晰:http://jsbin.com/uxaqima/2/edit?控制台
下面是在示例中包含数组的更详细的版本:http://jsbin.com/uxaqima/1/edit?控制台
Lodash版本3.10.1方法比较
_.merge(object, [sources], [customizer], [thisArg]) _.assign(object, [sources], [customizer], [thisArg]) _.extend(object, [sources], [customizer], [thisArg]) _.defaults(object, [sources]) _.defaultsDeep(object, [sources])
相似之处
- 它们中没有一个能像您预期的那样在数组上工作
_.extend 是_.assign 的别名,所以它们是相同的。- 它们似乎都修改了目标对象(第一个参数)
- 他们都是一模一样的
差异
_.defaults 和_.defaultsDeep 的处理顺序与其他的相反(尽管第一个参数仍然是目标对象)。_.merge 和_.defaultsDeep 将合并子对象,其他对象将在根级别覆盖。- 只有
_.assign 和_.extend 会用undefined 覆盖一个值。
测验它们都以类似的方式处理根节点上的成员。
1 2 3 4 | _.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" } |
1 2 3 4 | _.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" } |
他们处理
1 2 3 4 | _.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 } |
但是只有
1 2 3 4 | _.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" }} |
似乎他们都不会合并数组
1 2 3 4 | _.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" ] } |
全部修改目标对象
1 2 3 4 | 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将数组视为对象,其中键是数组的索引。
1 2 3 4 5 6 7 8 9 | _.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" ] |
另一个需要注意的区别是处理
1 2 3 4 | mergeInto = { a: 1} toMerge = {a : undefined, b:undefined} lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined} lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined} |
因此,
从语义的角度考虑它们的作用也可能很有帮助:
分配1 2 | 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) |
②合并
1 2 | merge is like assign but does not assign objects but replicates them instead. (deep copy) |
默认值
1 2 | provides default values for missing values. so will assign only values for keys that do not exist yet in the source. |
默认深度
1 2 | works like _defaults but like merge will not simply copy objects and will use recursion instead. |
我相信,从语义的角度学习这些方法会让你更好地"猜测"现有和不存在价值的所有不同情况下的行为。
如果您希望在保留相同的