I learned that when using Object.assign() it extends only the top level object. How can I deeply extend the object? For example, let's say I have the following source object:
const source = {
id: 1,
otherKey: {},
params: {
page: {
a: 1,
b: {}
},
data: {
b: 1
}
}
}
And I am using Object.assign()
like this:
Object.assign({}, source, {
params: {
page: {
a: 2
}
}
}
The result will be:
{
id: 1,
otherKey: {},
params: {
page: {
a: 2
}
}
}
How can I preserve the params.data key and the params.page.b key in a shallow clone way.
oldObject.params.data === newObject.params.data // true
oldObject.params.page === newObject.params.page // false
oldObject.params.page.b === newObject.params.page.b // true
Note: This question is not the same as How to deep merge instead of shallow merge. The answers there does not give the expected results.
Check this bin that takes an answer from the above link.
By using Object. assign() , you are actually doing Shallow Copy of your object. Whenever we do an operation like assigning one object to other, we actually perform a shallow copy, i.e. if OBJ1 is an object, modifying it through another object which is OBJ2 will reflect changes in OBJ1 too.
Object. assign() returns a target object. In case of a name collision between a source and target property, Object. assign() will overwrite the local property of the target object.
var clone = Object. assign({}, obj); The Object. assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.
So in your posted code, what happens is, if the source and target both contain the same key then nothing happens. The object is recursed down to the children. However if you simply change the inner block to this:
if (!target[key]) {
Object.assign(target, { [key]: {} });
}else{
target[key] = Object.assign({}, target[key])
}
mergeDeep(target[key], source[key]);
This will create a new assigned object for any key that is found in both the source and the target. Interestingly though, if you do this, your expected falseys
will not show up in the console. This is because the target will always match the result, as it is the final mutated object. So in order to get your expected false
results, you need to do something like the following:
var tester = source.params
const result = mergeDeep(source, b)
console.log(tester === result.params) // this will be false after the above addition
You can see your desired result here: http://jsbin.com/vicemiqiqu/1/edit?js,console
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With