javascript Object.assign()不覆盖字段



是否有任何方法可以合并两个对象,如Object.assign(a, b),但我希望a中相同的字段保持其原始值(不覆盖b)。

a = {x: 1, y: 2}
b = {y: 3, z: 4}
Object.assign(a, b)
// Now we get a = {x: 1, y: 3, z: 4}, so what if I want {x: 1, y: 2, z: 4}?
console.log(a) 

注意:感谢各位回答的努力,问题的关键要求是:

  1. 修改a
  2. 代码不多
  3. 不要太慢

要修改a引用(就像你似乎想从你的例子中做的那样),你可以这样做:

const a = {x: 1, y: 2};
const b = {y: 3, z: 4};
Object.assign(a, {...b, ...a});
console.log(a);

这实际上是说,将b中的重叠属性替换为a中的属性,然后将替换后的对象合并到a中。

上面,{...b, ...a}首先将ab合并,因此a覆盖b中的属性,得到:

{y: 3, z: 4, x: 1, y: 2}
// evalutes to
{z: 4, x: 1, y: 2}
现在我们将这个结果合并到aObject.assign()调用:
{x: 1, y: 2, z: 4, x: 1, y: 2}
// evalutes to
{z: 4, x: 1, y: 2}
// ie:
{x: 1, y: 2, z: 4}

编辑:为了满足您的需求,使用常规的for...in循环,它是有效的,不需要太多代码(特别是如果您删除块),并修改a:

const a = {x: 1, y: 2};
const b = {y: 3, z: 4};
for(const key in b) a[key] ??= b[key];
console.log(a); // {"x": 1, "y": 2, "z": 4}

如果你的值不为空(null/undefined),上面的工作,因为它使用逻辑空赋值(??=),否则,你可以用:

a[key] = key in a ? a[key] : b[key]; 

最好的解决方案是避免使用Object。分配和使用扩展运算符,通过这样做,您将通过简单的逻辑实现目标。在展开操作符中,最右边的元素覆盖最左边的元素。

a = {x: 1, y: 2};
b = {y: 3, z: 4};

result = {...b, ...a}; 
result2 = {...a, ...b};
console.log(result); // {x: 1, y: 2, z: 4} 
console.log(result2); // {x: 1, y: 3, z: 4} 
//if you don't want to create new object and just modify a then
Object.assign(a, {...b, ...a});
console.log(a); // {x: 1, y: 2, z: 4} 

let a = { x: 1, y: 2 };
let temp = { ...a };
let b = { y: 3, z: 4 };
Object.assign(a, b);
Object.assign(a, temp);
console.log(a);

您可以使用Object.entries并过滤掉已经在a中的键

a = {x: 1, y: 2}
b = {y: 3, z: 4}
//Object.assign(a, b)
// Now we get a = {x: 1, y: 3, z: 4}, so what if I want {x: 1, y: 2, z: 4}?
Object.assign(a, Object.fromEntries(
Object.entries(b).
filter(([k])=>!(k in a))));
console.log(a)

最后我找到了完美的解决方案是lodash.defaults

https://lodash.com/docs/4.17.15违约

import _ from 'lodash'
a = {x: 1, y: 2}
b = {y: 3, z: 4}
_.defaults(a, b)
// Outputs {x:1, y:2, z:4}, perfectly as expected.
console.log(a) 

最新更新