I might be misunderstanding how Object.assign()
works, but I wasn't expecting it to remove an existing property, eg.:
var o1 = { "status":"", "app":{"version":"1.3.1.91","latest_version":"1.3.1.91"} }
var o2 = { "status":"listening", "app":{"latest_version":"1.3.2.879"} }
console.log(Object.assign({}, o1, o2));
Output: {"status":"listening","app":{"latest_version":"1.3.2.879"}}
What I expected it to be: {"status":"listening", "app":{"version":"1.3.1.91", "latest_version":"1.3.2.879"}}
I guess it's because it's a nested object? Is there any to make it update nested objects automatically (ie. without having to specify which ones) without any library?
Thank you
I might be misunderstanding how Object.assign()
works, but I wasn't expecting it to remove an existing property, eg.:
var o1 = { "status":"", "app":{"version":"1.3.1.91","latest_version":"1.3.1.91"} }
var o2 = { "status":"listening", "app":{"latest_version":"1.3.2.879"} }
console.log(Object.assign({}, o1, o2));
Output: {"status":"listening","app":{"latest_version":"1.3.2.879"}}
What I expected it to be: {"status":"listening", "app":{"version":"1.3.1.91", "latest_version":"1.3.2.879"}}
I guess it's because it's a nested object? Is there any to make it update nested objects automatically (ie. without having to specify which ones) without any library?
Thank you
Share Improve this question asked Dec 13, 2017 at 11:25 CornwellCornwell 3,4108 gold badges54 silver badges85 bronze badges6 Answers
Reset to default 5Object.assign can't manage nested objects. You have to loop through the properties of your object.
The code below manage your case but if you want to work with more nested objects, do the proceess recursively
var o1 = { "status":"", "app":{"version":"1.3.1.91","latest_version":"1.3.1.91"} };
var o2 = { "status":"listening", "app":{"latest_version":"1.3.2.879"} };
var output = {};
Object.keys(o2).forEach(key => {
if (o2[key] instanceof Object) {
output[key] = Object.assign({}, o1[key], o2[key]);
} else {
output[key] = o2[key];
}
});
console.log(output);
var o1 = { a: 1, b: 1, c: 1 };
var o2 = { b: 2, c: 2 };
var o3 = { c: 3 };
var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
Object.assign will overwrite properties if objects that occur later have the same properties. In your case o1 properties are being overwritten by o2 properties. I don't think there is a way to achieve what you want using Object.assign.
Properties in the target object will be overwritten by properties in the sources if they have the same key. Later sources' properties will similarly overwrite earlier ones.
The Object.assign() method only copies enumerable and own properties from a source object to a target object. It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters. Therefore it assigns properties versus just copying or defining new properties.
states MDN. If you are down to use jQuery, this task can be simply done by $.extend()
(read more on api.jquery.com): Otherwise, you are very likely to write something like @Faly's answer.
var o1 = { "status":"", "app":{"version":"1.3.1.91","latest_version":"1.3.1.91"} }
var o2 = { "status":"listening", "app":{"latest_version":"1.3.2.879"} }
console.log($.extend(true, {}, o1, o2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use merge from lodash:
https://lodash.com/docs/4.17.15#merge
It does the same thing as assign, but on every level of the object. Just note that it doesn't return a new object.
With Object.assign the object have a same keys replace with last object.: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
var o1 = { status:"", app:{"version":"1.3.1.91","latest_version":"1.3.1.91"}};
var o2 = { status:"listening", app:{"latest_version":"1.3.2.879"} };
var {app: appo2} = o2
var {app: appo1} = o1
const result = {
...o2,
app: {
...appo1,
...appo2
}
}
console.log(result);
Another option could be nested assign:
var o1 = { status: "" , app: { "version":"1.3.1.91", "latest_version":"1.3.1.91" } }
var o2 = { status: "listening", app: { "latest_version":"1.3.2.879" } }
var o3 = Object.assign({}, o1, o2, { app: Object.assign(o1.app, o2.app) } )
var o4 = { ...o1, ...o2, app: { ...o1.app, ...o2.app } }
console.log( JSON.stringify(o3) )
console.log( JSON.stringify(o4) )