Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object.assign removing existing property

Tags:

javascript

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

like image 761
Cornwell Avatar asked Dec 13 '17 11:12

Cornwell


People also ask

Does object assign overwrite properties?

Description. Properties in the target object are overwritten by properties in the sources if they have the same key. Later sources' properties overwrite earlier ones. The Object.assign() method only copies enumerable and own properties from a source object to a target object.

How can a property be removed from an object?

Remove Property from an Object The delete operator deletes both the value of the property and the property itself. After deletion, the property cannot be used before it is added back again. The delete operator is designed to be used on object properties. It has no effect on variables or functions.

Does object assign do a deep copy?

Object. assign does not copy prototype properties and methods. This method does not create a deep copy of Source Object, it makes a shallow copy of the data. For the properties containing reference or complex data, the reference is copied to the destination object, instead of creating a separate object.


3 Answers

Object.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);
like image 118
Faly Avatar answered Sep 23 '22 09:09

Faly


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>
like image 41
curveball Avatar answered Sep 21 '22 09:09

curveball


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.

like image 36
Ingadi Avatar answered Sep 22 '22 09:09

Ingadi