답변:
방법은 다음 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.
시맨틱 관점에서 이러한 방법을 생각하는 법을 배우면 기존의 가치와 존재하지 않는 가치에 대한 모든 다른 시나리오에 대한 행동을 더 잘 추측 할 수 있다고 생각합니다.