最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Object.assign removing existing property - Stack Overflow

programmeradmin11浏览0评论

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 badges
Add a comment  | 

6 Answers 6

Reset to default 5

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);

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) )

发布评论

评论列表(0)

  1. 暂无评论