JavaScript/Coffeescript 求和对象

JavaScript/Coffeescript sum objects

我很乐意以这种方式 "add/merge"(不确定如何称呼)一些对象:

obj1 = { 
  a: 1,
  b: 1,
  c: 1
}

obj2 = { 
  a: 1,
  b: 1
}

obj1 + obj2 => { a: 2, b: 2, c: 1 }

有什么办法可以实现吗?已尝试,Object.assign(obj1, obj2) 但它不会像我需要的那样添加属性(returns in { a: 1, b: 1, c: 1})

快速回答:

let sum = {};
let keys = new Set(Object.keys(obj1))
Object.keys(obj2).map(x => keys = keys.add(x))

keys.forEach(x => {
 let op1 = obj1[x] || 0;
 let op2 = obj2[x] || 0;
 sum[x] = op1 + op2;
})

没有内置的方法来执行此操作,但您可以枚举一个对象的属性并将它们的值添加到另一个对象。

const a = { a: 1, b: 1, c: 1 };
const b = { a: 1, b: 1 };
for(const prop in b) {
  a[prop] = (prop in a ? a[prop] : 0) + b[prop];
}
console.log(a);

prop in a 检查是为了让我们不会通过将 undefined 添加到 b.

中的值而得到 NaN

您可以使用 reduce 组合 n 个对象,如下所示:

const a = { a: 1, b: 1, c: 1 };
const b = { a: 1, b: 1 };
const c = { a: 1, c: 1 };
const result = [a, b, c].reduce((p, c) => {
  for(const prop in c) {
    p[prop] = (prop in p ? p[prop] : 0) + c[prop];
  }
  return p;
}, {});
console.log(result);

你没有提到你想如何处理原型链中的属性。你应该知道 for...in 会枚举原型链中的属性, prop in x 也会检查原型链。如果您只想枚举对象自己的属性,那么您可以使用 Object.entries() 来获取它自己的属性,或者在 for...in 中进行 hasOwnProperty(...) 检查并代替 prop in x查看。如果您不对模型进行任何原型继承,那么您可能不在乎。

创建一个空对象:

var obj3 = {};

使用 spread operator 从两个对象中获取所有键,然后将它们添加到新对象中,如下所示:

for(var i in {...obj1, ...obj2}) {
  obj3[i] = (obj1[i] || 0) + (obj2[i] || 0);
}

var obj1 = { 
  a: 1,
  b: 1,
  c: 1
}

var obj2 = { 
  a: 1,
  b: 2,
  d: 3
}

var obj3 = {};

for(var i in {...obj1, ...obj2}) {
  obj3[i] = (obj1[i] || 0) + (obj2[i] || 0);
}

console.log(obj3);