Lodashライブラリで、誰かがmergeとextend / assignのより良い説明を提供できますか。
それは簡単な質問ですが、それでも答えは私を回避します。
Lodashライブラリで、誰かがmergeとextend / assignのより良い説明を提供できますか。
それは簡単な質問ですが、それでも答えは私を回避します。
extend
/の仕組みは次のassign
とおりです。ソースの各プロパティについて、その値をそのままコピー先にコピーします。プロパティ値自体がオブジェクトである場合、それらのプロパティの再帰的なトラバーサルはありません。オブジェクト全体がソースから取得され、宛先に設定されます。
merge
ソース内の各プロパティについて、そのプロパティがオブジェクト自体であるかどうかを確認します。その場合は、再帰的にダウンし、子オブジェクトのプロパティをソースから宛先にマップしてみてください。したがって、基本的に、ソースから宛先へのオブジェクト階層をマージします。extend
/の場合はassign
、ソースから宛先へのプロパティの単純な 1 レベルのコピーです。
これを明確にする単純な JSBin を次に示します: http://jsbin.com/uXaqIMa/2/edit?js,console
例にも配列を含むより精巧なバージョンがあります: http://jsbin.com/uXaqIMa/1/edit?js,console
_.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" ]
注意すべきもう 1 つの違いは、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
セマンティックな観点から、それらが何をするかを検討することも役立つかもしれません:
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.
セマンティックな観点からこれらのメソッドを考えることを学ぶことで、既存の値と存在しない値のすべての異なるシナリオでどのような動作になるかをよりよく「推測」できるようになると思います。